Skip to content

Instantly share code, notes, and snippets.

@ahmedfgad
Created June 4, 2019 14:38
Show Gist options
  • Save ahmedfgad/fe1913dbb89dcee9cf321b0bcf0903d5 to your computer and use it in GitHub Desktop.
Save ahmedfgad/fe1913dbb89dcee9cf321b0bcf0903d5 to your computer and use it in GitHub Desktop.
import kivy.app
import kivy.uix.gridlayout
import kivy.uix.boxlayout
import kivy.uix.button
import kivy.uix.textinput
import kivy.uix.label
import numpy
from kivy.config import Config
class BuzzleApp(kivy.app.App):
pop_created = 0 # 0 means a population is not yet created.
def initialize_population(self, *args):
self.num_solutions = numpy.uint8(self.num_solutions_TextInput.text)
self.reset_board_text()
self.population_1D_vector = numpy.zeros(shape=(self.num_solutions,8)) # Each solution is represented as a row in this array. If there are 5 rows, then there are 5 solutions.
# Creating the initial population RANDOMLY as a set of 1D vectors.
for solution_idx in range(self.num_solutions):
initial_queens_y_indices = numpy.random.rand(8) * 8
initial_queens_y_indices = initial_queens_y_indices.astype(numpy.uint8)
self.population_1D_vector[solution_idx, :] = initial_queens_y_indices
self.vector_to_matrix()
self.pop_created = 1 # indicates that the initial population is created in order to enable drawing solutions on GUI.
self.num_attacks_Label.text = "Initial Population Created."
def vector_to_matrix(self):
# Converts the 1D vector solutions into a 2D matrix solutions representing the board, where 1 means a queen exists. The matrix form of the solutions makes calculating the fitness value much easier.
self.population = numpy.zeros(shape=(self.num_solutions, 8, 8))
solution_idx = 0
for current_solution in self.population_1D_vector:
current_solution = numpy.uint8(current_solution)
row_idx = 0
for col_idx in current_solution:
self.population[solution_idx, row_idx, col_idx] = 1
row_idx = row_idx + 1
# print(self.population[solution_idx, :])
solution_idx = solution_idx + 1
def reset_board_text(self):
# Reset board on GUI.
for row_idx in range(self.all_widgets.shape[0]):
for col_idx in range(self.all_widgets.shape[1]):
self.all_widgets[row_idx, col_idx].text = "[color=ffffff]" + str(row_idx) + ", " + str(col_idx) + "[/color]"
with self.all_widgets[row_idx, col_idx].canvas.before:
kivy.graphics.Color(0, 0, 0, 1) # green; colors range from 0-1 not 0-255
self.rect = kivy.graphics.Rectangle(size=self.all_widgets[row_idx, col_idx].size,
pos=self.all_widgets[row_idx, col_idx].pos)
def build(self):
boxLayout = kivy.uix.boxlayout.BoxLayout(orientation="vertical")
gridLayout = kivy.uix.gridlayout.GridLayout(rows=8, size_hint_y=9)
boxLayout_buttons = kivy.uix.boxlayout.BoxLayout(orientation="horizontal")
boxLayout.add_widget(gridLayout)
boxLayout.add_widget(boxLayout_buttons)
# Preparing the 8x8 board.
self.all_widgets = numpy.zeros(shape=(8,8), dtype="O")
for row_idx in range(self.all_widgets.shape[0]):
for col_idx in range(self.all_widgets.shape[1]):
self.all_widgets[row_idx, col_idx] = kivy.uix.button.Button(text=str(row_idx)+", "+str(col_idx), font_size=25)
self.all_widgets[row_idx, col_idx].markup = True
gridLayout.add_widget(self.all_widgets[row_idx, col_idx])
# Preparing buttons inside the child BoxLayout.
initial_button = kivy.uix.button.Button(text="Initial Population", font_size=15, size_hint_x=2)
initial_button.bind(on_press=self.initialize_population)
ga_solution_button = kivy.uix.button.Button(text="Show Best Solution", font_size=15, size_hint_x=2)
start_ga_button = kivy.uix.button.Button(text="Start GA", font_size=15, size_hint_x=2)
self.num_solutions_TextInput = kivy.uix.textinput.TextInput(text="8", font_size=20, size_hint_x=1)
self.num_generations_TextInput = kivy.uix.textinput.TextInput(text="10000", font_size=20, size_hint_x=1)
self.num_mutations_TextInput = kivy.uix.textinput.TextInput(text="5", font_size=20, size_hint_x=1)
self.num_attacks_Label = kivy.uix.label.Label(text="# Attacks/Best Solution", font_size=15, size_hint_x=2)
boxLayout_buttons.add_widget(initial_button)
boxLayout_buttons.add_widget(ga_solution_button)
boxLayout_buttons.add_widget(start_ga_button)
boxLayout_buttons.add_widget(self.num_solutions_TextInput)
boxLayout_buttons.add_widget(self.num_generations_TextInput)
boxLayout_buttons.add_widget(self.num_mutations_TextInput)
boxLayout_buttons.add_widget(self.num_attacks_Label)
return boxLayout
Config.set('graphics', 'width', '1000')
Config.set('graphics', 'height', '600')
buzzleApp = BuzzleApp()
buzzleApp.run()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment