Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed last month.
Improve this question
How to add support for other languages (diacritics). It's a Scrabble playing code. I would like to add support for diacritics such as ô, ö, Ñ, æ, ą, ć, ę, ł, ń, ó, ś, ź, Ż. What modifications would make it possible. I have the correct word file but the characters are very problematic. Sincerely thank you all for your help
`
from letter_tree import basic_english
from board import sample_board
class SolveState:
def __init__(self, dictionary, board, rack):
self.dictionary = dictionary
self.board = board
self.rack = rack
self.cross_check_results = None
self.direction = None
def before(self, pos):
row, col = pos
if self.direction == 'across':
return row, col - 1
else:
return row - 1, col
def after(self, pos):
row, col = pos
if self.direction == 'across':
return row, col + 1
else:
return row + 1, col
def before_cross(self, pos):
row, col = pos
if self.direction == 'across':
return row - 1, col
else:
return row, col - 1
def after_cross(self, pos):
row, col = pos
if self.direction == 'across':
return row + 1, col
else:
return row, col + 1
def legal_move(self, word, last_pos):
print('found a word:', word)
board_if_we_played_that = self.board.copy()
play_pos = last_pos
word_idx = len(word) - 1
while word_idx >= 0:
board_if_we_played_that.set_tile(play_pos, word[word_idx])
word_idx -= 1
play_pos = self.before(play_pos)
print(board_if_we_played_that)
print()
def cross_check(self):
result = dict()
for pos in self.board.all_positions():
if self.board.is_filled(pos):
continue
letters_before = ""
scan_pos = pos
while self.board.is_filled(self.before_cross(scan_pos)):
scan_pos = self.before_cross(scan_pos)
letters_before = self.board.get_tile(scan_pos) + letters_before
letters_after = ""
scan_pos = pos
while self.board.is_filled(self.after_cross(scan_pos)):
scan_pos = self.after_cross(scan_pos)
letters_after = letters_after + self.board.get_tile(scan_pos)
if len(letters_before) == 0 and len(letters_after) == 0:
legal_here = list('abcdefghijklmnopqrstuvwxyz')
else:
legal_here = []
for letter in 'abcdefghijklmnopqrstuvwxyz':
word_formed = letters_before + letter + letters_after
if self.dictionary.is_word(word_formed):
legal_here.append(letter)
result[pos] = legal_here
return result
def find_anchors(self):
anchors = []
for pos in self.board.all_positions():
empty = self.board.is_empty(pos)
neighbor_filled = self.board.is_filled(self.before(pos)) or \
self.board.is_filled(self.after(pos)) or \
self.board.is_filled(self.before_cross(pos)) or \
self.board.is_filled(self.after_cross(pos))
if empty and neighbor_filled:
anchors.append(pos)
return anchors
def before_part(self, partial_word, current_node, anchor_pos, limit):
self.extend_after(partial_word, current_node, anchor_pos, False)
if limit > 0:
for next_letter in current_node.children.keys():
if next_letter in self.rack:
self.rack.remove(next_letter)
self.before_part(
partial_word + next_letter,
current_node.children[next_letter],
anchor_pos,
limit - 1
)
self.rack.append(next_letter)
def extend_after(self, partial_word, current_node, next_pos, anchor_filled):
if not self.board.is_filled(next_pos) and current_node.is_word and anchor_filled:
self.legal_move(partial_word, self.before(next_pos))
if self.board.in_bounds(next_pos):
if self.board.is_empty(next_pos):
for next_letter in current_node.children.keys():
if next_letter in self.rack and next_letter in self.cross_check_results[next_pos]:
self.rack.remove(next_letter)
self.extend_after(
partial_word + next_letter,
current_node.children[next_letter],
self.after(next_pos),
True
)
self.rack.append(next_letter)
else:
existing_letter = self.board.get_tile(next_pos)
if existing_letter in current_node.children.keys():
self.extend_after(
partial_word + existing_letter,
current_node.children[existing_letter],
self.after(next_pos),
True
)
def find_all_options(self):
for direction in ['across', 'down']:
self.direction = direction
anchors = self.find_anchors()
self.cross_check_results = self.cross_check()
for anchor_pos in anchors:
if self.board.is_filled(self.before(anchor_pos)):
scan_pos = self.before(anchor_pos)
partial_word = self.board.get_tile(scan_pos)
while self.board.is_filled(self.before(scan_pos)):
scan_pos = self.before(scan_pos)
partial_word = self.board.get_tile(scan_pos) + partial_word
pw_node = self.dictionary.lookup(partial_word)
if pw_node is not None:
self.extend_after(
partial_word,
pw_node,
anchor_pos,
False
)
else:
limit = 0
scan_pos = anchor_pos
while self.board.is_empty(self.before(scan_pos)) and self.before(scan_pos) not in anchors:
limit = limit + 1
scan_pos = self.before(scan_pos)
self.before_part("", self.dictionary.root, anchor_pos, limit)
solver = SolveState(basic_english(), sample_board(), ['e', 'f', 'f', 'e', 'c', 't'])
print(solver.board)
print()
solver.find_all_options()
`
You can use a simply module Unidecode for this.
from unidecode import unidecode
print(unidecode('žeuš'))
Output:
>>> zeus
Here is the code I currently have. The program works great I just want to make the game playable using sockets. If this game were ran on one computer, I would like two GUI windows to pop up but I am having a tough time doing so. I have used sockets to work with two different computers but I can't seem to implement it the way I want it at the moment.
import tkinter as tk
import random
import socket
import threading
possiblechoices = [["A","E","A","N","E","G"],["A","H","S","P","C","O"],["A","S","P","F","F","K"],["O","B","J","O","A","B"],["I","O","T","M","U","C"],["R","Y","V","D","E","L"],["L","R","E","I","X","D"],["E","I","U","N","E","S"],["W","N","G","E","E","H"],["L","N","H","N","R","Z"],["T","S","T","I","Y","D"],["O","W","T","O","A","T"],["E" ,"R" ,"T" ,"T" ,"Y" ,"L"],["T" ,"O" ,"E" ,"S" ,"S" ,"I"],["T", "E" ,"R" ,"W" ,"H" ,"V"],["N" ,"U" ,"I" ,"H" ,"M" ,"Qu"]]
words = []
with open('words.txt', 'r') as f:
for line in f:
for word in line.split():
newword = word.lower()
words.append(newword)
def new_board():
copy = [i for i in possiblechoices]
columns = []
for i in range(0,4):
columns.append([])
for j in range(0,4):
die = random.choice(copy)
columns[i].append(random.choice(die))
copy.remove(die)
return columns
def adjacent_cells(current_cell):
adj_list = []
x = current_cell[0]
y = current_cell[1]
# get cell above (if y > 0):
if y > 0:
adj_list.append((x, y-1))
# get cell below (if y < 3):
if y < 3:
adj_list.append((x, y+1))
# get left cell (if x > 0):
if x > 0:
adj_list.append((x-1, y))
# get right cell (if x < 3):
if x < 3:
adj_list.append((x+1, y))
# get upper left diagonal (if y > 0 and x > 0):
if y > 0 and x > 0:
adj_list.append((x-1, y-1))
# get upper right diagonal (if y > 0 and x < 3):
if y > 0 and x < 3:
adj_list.append((x+1, y-1))
# get lower left diagonal (if y < 3 and x > 0):
if y < 3 and x > 0:
adj_list.append((x-1, y+1))
# get lower right diagonal (if y < 3 and x < 3):
if y < 3 and x < 3:
adj_list.append((x+1, y+1))
return adj_list
def cells_with_letter(board, letter):
coords = []
for i in range(4):
for j in range(4):
if board[i][j] == letter:
coords.append((j, i))
return coords
def board_has_word(board, word, used_cells = None):
word = word.upper()
if word[0] =='Q' or word[0] =='q':
if used_cells is None:
starting_cells = cells_with_letter(board,"Qu")
if len(starting_cells) == 0:
return False
if len(word) == 2:
return True
else:
for s in starting_cells:
if board_has_word(board, word[2:], [s]):
return True
return False
else:
current_cell = used_cells[-1]
neighbors = adjacent_cells(current_cell)
neighbors = [c for c in neighbors if not c in used_cells]
neighbors = [c for c in neighbors if "Qu" == board[c[1]][c[0]]]
if len(neighbors) == 0:
return False
if len(word) == 2:
return True
else:
for n in neighbors:
if board_has_word(board, word[2:], used_cells + [n]):
return True
return False
if used_cells is None:
starting_cells = cells_with_letter(board, word[0])
if len(starting_cells) == 0:
return False
if len(word) == 1:
return True
else:
for s in starting_cells:
if board_has_word(board, word[1:], [s]):
return True
return False
else:
current_cell = used_cells[-1]
neighbors = adjacent_cells(current_cell)
neighbors = [c for c in neighbors if not c in used_cells]
neighbors = [c for c in neighbors if word[0] == board[c[1]][c[0]]]
if len(neighbors) == 0:
return False
if len(word) == 1:
return True
else:
for n in neighbors:
if board_has_word(board, word[1:], used_cells + [n]):
return True
return False
turn = True
player1score = 0
player2score = 0
usedwords = []
#tk drawing
root = tk.Tk()
frame = tk.Frame(root)
frame.grid(row=0, column=0)
copy = possiblechoices
board = new_board()
for x in range(len(board)):
for y in range(len(board[x])):
letter = board[x][y]
l = tk.Label(frame, text = letter)
l.grid(row = y, column = x)
l1 = tk.Label(root, text="Guess word:")
l1.grid(row=4, column=0)
e1 = tk.Entry(root)
e1.grid(row=4, column=1)
l2 = tk.Label(root, text="You guessed: ")
l2.grid(row=5, column=0)
l3 = tk.Label(root, text="")
l3.grid(row=5, column=1)
#player 1 score
l4 = tk.Label(root, text = "Player 1 Score:")
l4.grid(row = 2,column = 0)
l5 = tk.Label(root, text = (player1score))
l5.grid(row = 2, column = 1)
#payer 2 score
l8 = tk.Label(root, text = "Player 2 Score:")
l8.grid(row = 3, column =0)
l9 = tk.Label(root, text = player2score)
l9.grid(row = 3, column = 1)
#Used words
l6 = tk.Label(root, text = "Used Words")
l6.grid(row = 2, column = 3)
l7 = tk.Label(root, text = usedwords)
l7.grid(row = 3, column = 3)
def make_guess():
global turn
maybe = e1.get().lower()
if(board_has_word(board, maybe)):
if maybe in words:
if maybe not in usedwords:
usedwords.append(maybe)
if(turn):
current = l5["text"]
converted = int(current)
if(not turn):
current = l9["text"]
converted = int(current)
l3.config(text=e1.get().lower())
l7.config(text =usedwords)
if len(maybe) >=3 and len(maybe) <=4:
converted+= 1
if len(maybe) ==5:
converted += 2
if len(maybe) ==6:
converted +=3
if len(maybe) ==7:
converted+=5
if len(maybe) >=8:
converted +=11
if(turn):
l5.config(text = str(converted))
turn = False
elif(not turn):
l9.config(text = str(converted))
turn = True
else:
l3.config(text = "Word already used")
if(turn):
turn = False
elif(not turn):
turn = True
else:
l3.config(text = "Not in dictionary")
else:
l3.config(text = "Word not in board")
def resetgame():
global board
global usedwords
board = new_board()
for x in range(len(board)):
for y in range(len(board[x])):
letter = board[x][y]
l = tk.Label(frame, text = letter)
l.grid(row = y, column = x)
l5.config(text = "0")
l9.config(text = "0")
usedwords = []
l7.config(text = usedwords)
l3.config(text = "")
reset = tk.Button(root, text = 'Reset Game', command = resetgame)
reset.grid(row = 6, column = 5, sticky = tk.W, pady = 4)
b1 = tk.Button(root, text='Submit',command=make_guess)
b1.grid(row=6, column=0, sticky=tk.W, pady=4)
tk.mainloop()
A few days ago a started making my simple board game. First of all, I generate a board for the game. It looks like this:
the gameboard generated for 13x13
Secondly, I place my character on the board, which is 'A':
The player placed
I made a dice for it which generates numbers from 1 to 6.
My goal right now is to get the 'A' character moving around by the dice on the '*' symbols, until it gets at the top left corner:
I need to get here by the dice
So here is my code that I tried:
import math
import random
import os
board= []
def generator(boardsize):
for row in range(boardsize+1):
brow = []
for column in range(boardsize+1):
if row == column == 0:
brow.append(' ')
elif row==0:
brow.append(str(column-1)[-1])
elif column==0:
brow.append(str(row-1)[-1])
elif ((math.ceil(boardsize/2)-1 )<= column) and(column <= (math.ceil(boardsize/2)+1)) or ((math.ceil(boardsize/2)-1 )<= row) and(row <= (math.ceil(boardsize/2)+1)):
if row == 1 or column == 1 or row == boardsize or column == boardsize:
brow.append('*')
else:
if row == (math.ceil(boardsize/2)) and column == (math.ceil(boardsize/2)):
brow.append('X')
elif row == (math.ceil(boardsize/2)) or column == (math.ceil(boardsize/2)):
brow.append('D')
else:
brow.append('*')
else:
brow.append(' ')
board.append(brow)
return board
def print_table(x):
os.system('cls')
for x in board:
print(' '.join(x))
number_from_dice= []
def dice():
min = 1
max = 6
x = random.randint(min, max)
number_from_dice[:]= [x]
return number_from_dice
def player1(x):
generator(x)
prev_char_y = 1
prev_char_x = math.ceil(x/2)+1
char_y= 1
char_x= math.ceil(x/2)+1
board[char_y][char_x] = "A"
print_table(x)
dice()
f = number_from_dice[0]
for i in range(f):
if(char_y<x):
if (board[char_y+1][char_x]) == '*':
char_y= char_y +1
board[char_y][char_x] = "A"
board[prev_char_y][prev_char_x] = '*'
prev_char_x = char_x
prev_char_y = char_y
print_table(x)
else:
if(char_x!=x):
char_x2 = char_x
if (board[char_y][char_x+1]=='*'):
char_x = char_x +1
board[char_y][char_x] = "A"
board[prev_char_y][prev_char_x] = '*'
prev_char_x = char_x
prev_char_y = char_y
print_table(x)
else:
if (board[char_y+1][char_x]) == '*':
char_y= char_y +1
board[char_y][char_x] = "A"
board[prev_char_y][prev_char_x] = '*'
prev_char_x = char_x
prev_char_y = char_y
print_table(x)
else:
if (board[char_y][char_x2-1]) == '*':
char_x2 = char_x2 -1
board[char_y][char_x2] = "A"
board[prev_char_y][prev_char_x] = '*'
prev_char_x = char_x2
prev_char_y = char_y
print_table(x)
else:
if (board[char_y+1][char_x2]) == '*':
char_y = char_y +1
board[char_y][char_x2] = "A"
board[prev_char_y][prev_char_x] = '*'
prev_char_x = char_x2
prev_char_y = char_y
print_table(x)
print('Number from dice: ', end='')
print(f)
player1(13)
Does the technic I used have potential? Or is it too complicated? How would you do it?
Just in a generic sense you've made it overly complicated.
Consider this - the board, as far as movement is concerned, is just a set of ordered spaces.
But right now you have information about how the board is created as part of the player code.
Best to separate this, and you will find that things get simpler.
Instead, have the player simply track it's progress, in other words, what numbered space is it on.
Then you can generate the board and, knowing the space numbers, you can see if it matches the player location.
And then take it one step further (and simpler still) and just draw the board on a 2D array, and then output that, instead of trying to figure out the board as you go line-by-line.
I am trying to program a version of conway's game of life however I keep getting the message 'Cell' Object Has no attribute 'nextState' when it seems like it should declare the value of nextState before asking to reference it. here is my code:
from tkinter import *
root = Tk()
class Cell (Button):
Dead = 0
Live = 1
def __init__ (self,parent):
Button.__init__(self,parent, relief = "raised" , width = 2 , borderwidth = 1 , command = self.onpress)
self.displayState(Cell.Dead)
def onpress (self):
if self.state == Cell.Live:
self.displayState(Cell.Dead)
elif self.state == Cell.Dead:
self.displayState(Cell.Live)
def setNextState (self , Neighbours):
if self.state == Cell.Live and (Neighbours < 2 or Neighbours > 3):
self.nextState = Cell.Dead
elif self.state == Cell.Dead and Neighbours == 3:
self.nextState = Cell.Live
elif self.state == Cell.Dead and Neighbours != 3:
self.nextState = self.state
def stepToNextState(self):
self.displayState(self.nextState)
def displayState (self , newstate):
self.state = newstate
if self.state == Cell.Live:
self["bg"] = "black"
if self.state == Cell.Dead:
self["bg"] = "white"
class Grid:
def __init__(self,parent,sizex,sizey):
self.sizex = sizex
self.sizey = sizey
self.cells = []
for a in range (0,self.sizex):
rowcells = []
for b in range (0, self.sizey):
c = Cell(parent)
c.grid(row=b , column=a)
rowcells.append(c)
self.cells.append(rowcells)
def step (self):
cells = self.cells
for x in range (0,self.sizex):
if x==0: x_down = self.sizex-1
else: x_down = x-1
if x==self.sizex-1: x_up = 0
else: x_up = x+1
for y in range(0,self.sizey):
if y==0: y_down = self.sizey-1
else: Y_down = y-1
if y==self.sizey-1: y_up = 0
else: y_up = y+1
sum = cells[x_down][y].state + cells[x_up][y].state + cells[x][y_down].state + cells[x][y_up].state + cells[x_down][y_down].state +cells[x_up][y_up].state + cells[x_down][y_up].state + cells[x_up][y_down].state
cells[x][y].setNextState(sum)
for row in cells:
for cell in row:
cell.stepToNextState()
def clear(self):
for row in self.cells:
for cell in row:
cell.displayState(Cell.Dead)
if __name__ == "__main__":
frame = Frame(root)
frame.pack()
grid = Grid(frame,25,25)
bottomFrame = Frame(root)
bottomFrame.pack (side = BOTTOM)
buttonStep = Button(bottomFrame , text="Step" , command=grid.step)
buttonStep.pack(side = LEFT)
buttonClear = Button(bottomFrame, text = "Clear", command=grid.clear)
buttonClear.pack(side=LEFT , after=buttonStep)
root.mainloop()
The error message is:
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Python33\lib\tkinter\__init__.py", line 1442, in __call__
return self.func(*args)
File "C:\Users\Owner\Desktop\Other\Programs & Misc\Python\Tyler's Game of Life.py", line 65, in step
cell.stepToNextState()
File "C:\Users\Owner\Desktop\Other\Programs & Misc\Python\Tyler's Game of Life.py", line 27, in stepToNextState
self.displayState(self.nextState)
AttributeError: 'Cell' object has no attribute 'nextState'
If anyone could point out where the error is occuring / what is causing it and possibly a way to fix it I would be very grateful.
The issue appears to be that your for row in cells loop is inside of your previous for x in range(0, self.sizex) loop. Here's what the step method should look like if you get it correctly indented:
def step (self):
cells = self.cells
for x in range (0,self.sizex):
if x==0: x_down = self.sizex-1
else: x_down = x-1
if x==self.sizex-1: x_up = 0
else: x_up = x+1
for y in range(0,self.sizey):
if y==0: y_down = self.sizey-1
else: Y_down = y-1
if y==self.sizey-1: y_up = 0
else: y_up = y+1
sum = cells[x_down][y].state + cells[x_up][y].state + cells[x][y_down].state + cells[x][y_up].state + cells[x_down][y_down].state +cells[x_up][y_up].state + cells[x_down][y_up].state + cells[x_up][y_down].state
cells[x][y].setNextState(sum)
for row in cells: # unindent these
for cell in row: # lines by one
cell.stepToNextState() # level each
If all the indentation issues are taken care of (or were not in the original code), there's still an issue that may cause an issue in certain situations. The issue is that the Cell.setNextState method doesn't handle every situation. Specifically, it doesn't set nextState if a cell is alive and should stay so (it has two or three living neighbors). The lack of an else on your chain of if and elif statements should have raised this as a red flag for me, but I overlooked it the first time I examined the function.
Here's how it can be fixed:
def setNextState (self , Neighbours):
if self.state == Cell.Live and (Neighbours < 2 or Neighbours > 3):
self.nextState = Cell.Dead
elif self.state == Cell.Dead and Neighbours == 3:
self.nextState = Cell.Live
else: # remove the conditions on this block, all the state changes were handled above
self.nextState = self.state
I am currently working on my Python game, in ika, which uses python 2.5
I decided to use A* pathfinding for the AI. However, I find it too slow for my needs (3-4 enemies can lag the game, but I would like to supply up to 4-5 without problems). I know, that such complex search like A* is not mean to be scripted in python, but I am pretty sure, that my pathfinder is also implemented in the wrong way.
My question is: How can I speed up this algorithm?
I wrote my own binary heap, and there are some try: except: lines inside some functions. Those lines can create large overhead? Are there better methods maintaining the open list?
I supplied the algorithm with graphics interface, for testing purposes (when the pathfinder finishes searching, it will write the number of iterations and seconds it takes to find the path, inside the ika.txt file. Also, Pressing A will do a complete search, and S does that step by step.)
Graphical version:
http://data.hu/get/6084681/A_star.rar
Also, here is a pastebin version:
http://pastebin.com/9N8ybX5F
Here is the main code I use for pathfinding:
import ika
import time
class Node:
def __init__(self,x,y,parent=None,g=0,h=0):
self.x = x
self.y = y
self.parent = parent
self.g = g
self.h = h
def cost(self):
return self.g + self.h
def equal(self,node):
if self.x == node.x and self.y == node.y:
return True
else:
return False
class Emerald_Pathfinder:
def __init__(self):
pass
def setup(self,start,goal):
self.start = start
self.goal = goal
self.openlist = [None,start] # Implemented as binary heap
self.closedlist = {} # Implemented as hash
self.onopenlist = {} # Hash, for searching the openlist
self.found = False
self.current = None
self.iterations = 0
def lowest_cost(self):
pass
def add_nodes(self,current):
nodes = []
x = current.x
y = current.y
self.add_node(x+1,y,current,10,nodes)
self.add_node(x-1,y,current,10,nodes)
self.add_node(x,y+1,current,10,nodes)
self.add_node(x,y-1,current,10,nodes)
# Dont cut across corners
up = map.is_obstacle((x,y-1),x,y-1)
down = map.is_obstacle((x,y+1),x,y+1)
left = map.is_obstacle((x-1,y),x-1,y)
right = map.is_obstacle((x+1,y),x+1,y)
if right == False and down == False:
self.add_node(x+1,y+1,current,14,nodes)
if left == False and up == False:
self.add_node(x-1,y-1,current,14,nodes)
if right == False and up == False:
self.add_node(x+1,y-1,current,14,nodes)
if left == False and down == False:
self.add_node(x-1,y+1,current,14,nodes)
return nodes
def heuristic(self,x1,y1,x2,y2):
return (abs(x1-x2)+abs(y1-y2))*10
def add_node(self,x,y,parent,cost,list):
# If not obstructed
if map.is_obstacle((x,y),x,y) == False:
g = parent.g + cost
h = self.heuristic(x,y,self.goal.x,self.goal.y)
node = Node(x,y,parent,g,h)
list.append(node)
def ignore(self,node,current):
# If its on the closed list, or open list, ignore
try:
if self.closedlist[(node.x,node.y)] == True:
return True
except:
pass
# If the node is on the openlist, do the following
try:
# If its on the open list
if self.onopenlist[(node.x,node.y)] != None:
# Get the id number of the item on the real open list
index = self.openlist.index(self.onopenlist[(node.x,node.y)])
# If one of the coordinates equal, its not diagonal.
if node.x == current.x or node.y == current.y:
cost = 10
else:
cost = 14
# Check, is this items G cost is higher, than the current G + cost
if self.openlist[index].g > (current.g + cost):
# If so, then, make the list items parent, the current node.
self.openlist[index].g = current.g + cost
self.openlist[index].parent = current
# Now resort the binary heap, in the right order.
self.resort_binary_heap(index)
# And ignore the node
return True
except:
pass
return False
def resort_binary_heap(self,index):
m = index
while m > 1:
if self.openlist[m/2].cost() > self.openlist[m].cost():
temp = self.openlist[m/2]
self.openlist[m/2] = self.openlist[m]
self.openlist[m] = temp
m = m / 2
else:
break
def heap_add(self,node):
self.openlist.append(node)
# Add item to the onopenlist.
self.onopenlist[(node.x,node.y)] = node
m = len(self.openlist)-1
while m > 1:
if self.openlist[m/2].cost() > self.openlist[m].cost():
temp = self.openlist[m/2]
self.openlist[m/2] = self.openlist[m]
self.openlist[m] = temp
m = m / 2
else:
break
def heap_remove(self):
if len(self.openlist) == 1:
return
first = self.openlist[1]
# Remove the first item from the onopenlist
self.onopenlist[(self.openlist[1].x,self.openlist[1].y)] = None
last = self.openlist.pop(len(self.openlist)-1)
if len(self.openlist) == 1:
return last
else:
self.openlist[1] = last
v = 1
while True:
u = v
# If there is two children
if (2*u)+1 < len(self.openlist):
if self.openlist[2*u].cost() <= self.openlist[u].cost():
v = 2*u
if self.openlist[(2*u)+1].cost() <= self.openlist[v].cost():
v = (2*u)+1
# If there is only one children
elif 2*u < len(self.openlist):
if self.openlist[2*u].cost() <= self.openlist[u].cost():
v = 2*u
# If at least one child is smaller, than parent, swap them
if u != v:
temp = self.openlist[u]
self.openlist[u] = self.openlist[v]
self.openlist[v] = temp
else:
break
return first
def iterate(self):
# If the open list is empty, exit the game
if len(self.openlist) == 1:
ika.Exit("no path found")
# Expand iteration by one
self.iterations += 1
# Make the current node the lowest cost
self.current = self.heap_remove()
# Add it to the closed list
self.closedlist[(self.current.x,self.current.y)] = True
# Are we there yet?
if self.current.equal(self.goal) == True:
# Target reached
self.goal = self.current
self.found = True
print self.iterations
else:
# Add the adjacent nodes, and check them
nodes_around = self.add_nodes(self.current)
for na in nodes_around:
if self.ignore(na,self.current) == False:
self.heap_add(na)
def iterateloop(self):
time1 = time.clock()
while 1:
# If the open list is empty, exit the game
if len(self.openlist) == 1:
ika.Exit("no path found")
# Expand iteration by one
self.iterations += 1
# Make the current node the lowest cost
self.current = self.heap_remove()
# Add it to the closed list
self.closedlist[(self.current.x,self.current.y)] = True
# Are we there yet?
if self.current.equal(self.goal) == True:
# Target reached
self.goal = self.current
self.found = True
print "Number of iterations"
print self.iterations
break
else:
# Add the adjacent nodes, and check them
nodes_around = self.add_nodes(self.current)
for na in nodes_around:
if self.ignore(na,self.current) == False:
self.heap_add(na)
time2 = time.clock()
time3 = time2-time1
print "Seconds to find path:"
print time3
class Map:
def __init__(self):
self.map_size_x = 20
self.map_size_y = 15
self.obstructed = {} # Library, containing x,y couples
self.start = [2*40,3*40]
self.unit = [16*40,8*40]
def is_obstacle(self,couple,x,y):
if (x >= self.map_size_x or x < 0) or (y >= self.map_size_y or y < 0):
return True
try:
if self.obstructed[(couple)] != None:
return True
except:
return False
def render_screen():
# Draw the Character
ika.Video.DrawRect(map.start[0],map.start[1],map.start[0]+40,map.start[1]+40,ika.RGB(40,200,10),1)
# Draw walls
for x in range(0,map.map_size_x):
for y in range(0,map.map_size_y):
if map.is_obstacle((x,y),x,y) == True:
ika.Video.DrawRect(x*40,y*40,(x*40)+40,(y*40)+40,ika.RGB(168,44,0),1)
# Draw openlist items
for node in path.openlist:
if node == None:
continue
x = node.x
y = node.y
ika.Video.DrawRect(x*40,y*40,(x*40)+40,(y*40)+40,ika.RGB(100,100,100,50),1)
# Draw closedlist items
for x in range(0,map.map_size_x):
for y in range(0,map.map_size_y):
try:
if path.closedlist[(x,y)] == True:
ika.Video.DrawRect(x*40,y*40,(x*40)+20,(y*40)+20,ika.RGB(0,0,255))
except:
pass
# Draw the current square
try:
ika.Video.DrawRect(path.current.x*40,path.current.y*40,(path.current.x*40)+40,(path.current.y*40)+40,ika.RGB(128,128,128), 1)
except:
pass
ika.Video.DrawRect(mouse_x.Position(),mouse_y.Position(),mouse_x.Position()+8,mouse_y.Position()+8,ika.RGB(128,128,128), 1)
# Draw the path, if reached
if path.found == True:
node = path.goal
while node.parent:
ika.Video.DrawRect(node.x*40,node.y*40,(node.x*40)+40,(node.y*40)+40,ika.RGB(40,200,200),1)
node = node.parent
# Draw the Target
ika.Video.DrawRect(map.unit[0],map.unit[1],map.unit[0]+40,map.unit[1]+40,ika.RGB(128,40,200),1)
def mainloop():
while 1:
render_screen()
if mouse_middle.Pressed():
# Iterate pathfinder
if path.found == False:
path.iterateloop()
elif mouse_right.Pressed():
# Iterate pathfinder by one
if path.found == False:
path.iterate()
elif ika.Input.keyboard["A"].Pressed():
# Iterate pathfinder
if path.found == False:
path.iterateloop()
elif ika.Input.keyboard["S"].Pressed():
# Iterate pathfinder by one
if path.found == False:
path.iterate()
elif mouse_left.Position():
# Add a square to the map, to be obstructed
if path.iterations == 0:
x = mouse_x.Position()
y = mouse_y.Position()
map.obstructed[(int(x/40),int(y/40))] = True
# Mouse preview
x = mouse_x.Position()
y = mouse_y.Position()
mx = int(x/40)*40
my = int(y/40)*40
ika.Video.DrawRect(mx,my,mx+40,my+40,ika.RGB(150,150,150,70),1)
ika.Video.ShowPage()
ika.Input.Update()
map = Map()
path = Emerald_Pathfinder()
path.setup(Node(map.start[0]/40,map.start[1]/40),Node(map.unit[0]/40,map.unit[1]/40))
mouse_middle = ika.Input.mouse.middle
mouse_right = ika.Input.mouse.right
mouse_left = ika.Input.mouse.left
mouse_x = ika.Input.mouse.x
mouse_y = ika.Input.mouse.y
# Initialize loop
mainloop()
I appreciate any help!
(sorry for any spelling mistakes, English is not my native language)
I think a proper implementation in python will be fast enough for your purposes. But the boost library has an astar implementation and python bindings. https://github.com/erwinvaneijk/bgl-python