Skip to content
Snippets Groups Projects
Commit 38c54ba2 authored by Sean Paeglis's avatar Sean Paeglis
Browse files

fa

parent 17301e8f
No related branches found
No related tags found
No related merge requests found
def recursive_move_finder(state_array, depth, max_depth):
if(depth == max_depth):
return evaluation_fn(stat_array[depth])
moves = state_array[depth].get_moves(board.colours((depth-1)%3))
if(depth==1):
expected_eval = -100000
for move in moves:
array_apply_move(state_array, depth, move)
new_eval = recursive_move_finder( state_array, depth+1, max_depth)
if(new_eval > expected_eval):
expected_eval = new_eval
best_move = move
array_undo_move(state_array, depth, move)
return best_move
if((depth-1)%3==0):
expected_eval = -100000
for move in moves:
array_apply_move(state_array, depth, move)
new_eval = recursive_move_finder( state_array, depth+1, max_depth)
if(new_eval > expected_eval):
expected_eval = new_eval
array_undo_move(state_array, depth, move)
return expected_eval
else:
expected_eval = 100000
for move in moves:
array_apply_move(state_array, depth, move)
new_eval = recursive_move_finder( state_array, depth+1, max_depth)
if(new_eval < expected_eval):
expected_eval = new_eval
array_undo_move(state_array, depth, move)
return expected_eval
def array_apply_move(state_array, depth, move):
for i in range(len(state_array)-depth):
state_array[depth+i].move(move)
def array_undo_move(state_array, depth, move):
for i in range(len(state_array)-depth):
state_array[depth+i].undo_move(move)
def on_board(self, q, r):
if q >= 0 and q <= 6 and r >= 0 and r <= 6:
return True
else:
return False
def getMoves(self, colour):
valid_moves = []
for piece in self.pieces[colour]:
q = piece.pos[0]
r = piece.pos[1]
# Otherwise, try all moves and return valid ones
for direction in self.directions:
q_moved = q + direction[0]
r_moved = r + direction[1]
if(on_board(q_moved, r_moved) && self.tiles[q_moved][r_moved] is None):
valid_moves.append(('MOVE',(q, r),(q_moved, r_moved)))
else
q_jumped = q_moved + direction[0]
r_jumped = r_moved + direction[1]
if(on_board(q_jumped, r_jumped) && self.tiles[q_jumped][r_jumped] is None):
valid_moves.append(('JUMP',(q, r),(q_jumped, r_jumped)))
if piece.pos in self.exit_tiles[colour]:
valid_moves.append(('EXIT',(q, r)))
if len(valid_moves) == 0:
valid_moves.append(('PASS',))
return valid_moves
def recursive_move_finder(state_array, depth, max_depth):
if(depth == max_depth):
return evaluation_fn(stat_array[depth])
moves = state_array[depth].get_moves(board.colours((depth-1)%3))
if(depth==1):
expected_eval = -100000
for move in moves:
array_apply_move(state_array, depth, move)
new_eval = recursive_move_finder( state_array, depth+1, max_depth)
if(new_eval > expected_eval):
expected_eval = new_eval
best_move = move
array_undo_move(state_array, depth, move)
return best_move
if((depth-1)%3==0):
expected_eval = -100000
for move in moves:
array_apply_move(state_array, depth, move)
new_eval = recursive_move_finder( state_array, depth+1, max_depth)
if(new_eval > expected_eval):
expected_eval = new_eval
array_undo_move(state_array, depth, move)
return expected_eval
else:
expected_eval = 100000
for move in moves:
array_apply_move(state_array, depth, move)
new_eval = recursive_move_finder( state_array, depth+1, max_depth)
if(new_eval < expected_eval):
expected_eval = new_eval
array_undo_move(state_array, depth, move)
return expected_eval
def array_apply_move(state_array, depth, move):
for i in range(len(state_array)-depth):
state_array[depth+i].move(move)
def array_undo_move(state_array, depth, move):
for i in range(len(state_array)-depth):
state_array[depth+i].undo_move(move)
def move(self, move):
move_from = move[1][0]
move_to = move[1][1]
if move[0] == 'MOVE':
shift_piece(move_from, move_to)
elif move[0] == 'JUMP':
piece = self.tiles[move_from[1]][move_from[0]]
direction = move_direction(move_from,move_to)
mid_tile = (piece.pos[0] + direction[0], piece.pos[1] + direction[1])
capture_piece(mid_tile, piece.colour)
shift_piece(move_from, move_to)
elif move[0] == 'EXIT':
piece = self.tiles[move[1][1]][move[1][0]]
self.tiles[move[1][1]][move[1][0]] = None
self.pieces[piece.colour].remove(piece)
def undo_move(self, move, colour):
move_from = move[1][1]
back_to = move[1][0]
if move[0] == 'MOVE':
shift_piece(move_from, move_to)
elif move[0] == 'JUMP':
piece = self.tiles[move_from[1]][move_from[0]]
direction = move_direction(move_from,move_to)
mid_tile = (piece.pos[0] + direction[0], piece.pos[1] + direction[1])
capture_piece(mid_tile, self.tiles[mid_tile[1]][mid_tile[0]])
shift_piece(move_from, move_to)
elif move[0] == 'EXIT':
piece = Piece.Piece(move[1], colour)
self.tiles[move[1][1]][move[1][0]] = piece
self.pieces[piece.colour].append(piece)
def capture_piece(self, pos, colour):
taken_piece = self.tiles[pos[1]][pos[0]]
for i in range(len(self.pieces[taken_piece.colour])):
if self.pieces[taken_piece.colour][i] is taken_piece:
self.pieces[taken_piece.colour].pop(i)
self.pieces[colour].append(taken_piece)
taken_piece.colour = colour
break
def shift_piece(self, t_from, t_to):
piece = self.tiles[t_from[1]][t_from[0]]
self.tiles[t_from[1]][t_from[0]] = None
self.tiles[t_to[1]][t_to[0]] = piece
piece.pos = t_to
def move_direction(move_from, move_to):
direction = (move_to[0]-move_from[0], move_to[1]-move_from[1])
return (int(direction[0]/2), int(direction[1]/2))
from Snek.util import Board from Snek.util import Board
import pickle
class Player: class Player:
def __init__(self, colour): def __init__(self, colour):
self.colour = colour self.colour = colour
self.board = Board.Board(self.colour) #self.board = Board.Board(self.colour)
states = []
for i in range(6):
states.append(Board.Board(self.colour))
def on_board(self, piece, move): def on_board(self, piece, move):
if piece.pos[0] + move[0] < -3 or piece.pos[0] + move[0] > 3: if piece.pos[0] + move[0] < -3 or piece.pos[0] + move[0] > 3:
...@@ -16,11 +20,115 @@ class Player: ...@@ -16,11 +20,115 @@ class Player:
return True return True
def action(self): def action(self):
"""
moves = self.board.get_moves(self.colour) moves = self.board.get_moves(self.colour)
moves[0] = self.board.convert_coords_ref(moves[0]) moves[0] = self.board.convert_coords_ref(moves[0])
print(moves[0]) print(moves[0])
return(moves[0]) return(moves[0])
"""
def update(self, colour, action): def update(self, colour, action):
action = self.board.convert_coords_local(action) action = self.board.convert_coords_local(action)
self.board.move(action) self..move(action)
def recursive_move_finder(self, state_array, depth, max_depth):
if(depth == max_depth):
return evaluation_fn(stat_array[depth], Board.colours[(depth-1)%3])
moves = state_array[depth].get_moves(board.colours[(depth-1)%3])
if(depth==1):
expected_eval = -100000
for move in moves:
array_apply_move(state_array, depth, move)
new_eval = recursive_move_finder( state_array, depth+1, max_depth)
if(new_eval > expected_eval):
expected_eval = new_eval
best_move = move
array_undo_move(state_array, depth, move, board.colours[(depth-1)%3])
return best_move
if((depth-1)%3==0):
expected_eval = -100000
for move in moves:
array_apply_move(state_array, depth, move)
new_eval = recursive_move_finder( state_array, depth+1, max_depth)
if(new_eval > expected_eval):
expected_eval = new_eval
array_undo_move(state_array, depth, move, board.colours[(depth-1)%3])
return expected_eval
else:
expected_eval = 100000
for move in moves:
array_apply_move(state_array, depth, move)
new_eval = recursive_move_finder( state_array, depth+1, max_depth)
if(new_eval < expected_eval):
expected_eval = new_eval
array_undo_move(state_array, depth, move, board.colours[(depth-1)%3])
return expected_eval
def array_apply_move(self, state_array, depth, move):
for i in range(len(state_array)-depth):
state_array[depth+i].move(move)
def array_undo_move(self, state_array, depth, move):
for i in range(len(state_array)-depth):
state_array[depth+i].undo_move(move)
def evaluation_fn(self, state):
evl = 0
for piece in state.pieces[self.board.colour]:
evl += ((min_dist(piece)-position_value(node, piece))/2 + 1)
return evl
def min_dist(self, piece):
min_dist = 10
for tile in self.board.exit_tiles[piece.colour]:
if self.board.distance(piece.pos, tile) <= min_dist:
min_dist = board.distance(piece.pos, tile)
return min_dist
# Calculates a "score" for a position based on the number of available jumps
# that get you closer to the goal state
def position_value(node, piece):
adjacent_piece = pickle.loads(pickle.dumps(piece))
value = 0
if piece.pos in self.board.exit_tiles[piece.colour]:
return value
for move in node.moves:
adjacent_piece.pos = (piece.pos[0] + move[0], piece.pos[1] + move[1])
adjacent_min = min_dist(adjacent_piece)
current_min = min_dist(piece)
if checkJump(node, piece.pos, move) and on_board(adjacent_piece.pos):
if adjacent_min < current_min:
value += 0.5
if adjacent_min == current_min:
value += 0.25
if adjacent_min == current_min+1:
value += 0.15
if (
on_board(adjacent_piece.pos) and
type(node.tiles[adjacent_piece.pos[1]+3][adjacent_piece.pos[0]+3]) == Piece.Piece
):
value += 0.1
return value
# Check if a jump is possible from a position in a given direction
def checkJump(node, position, move):
new = (position[0] + move[0], position[1] + move[1])
new_jump = (position[0] + 2*move[0], position[1] + 2*move[1])
if on_board(new) and on_board(new_jump):
if (
type(board.tiles[new[0]+3][new[1]+3]) == Piece.Piece and
type(board.tiles[new_jump[0]+3][new_jump[1]+3]) == None
):
return True
else:
return False
# Check if a position is on the board
def on_board(position):
if position[0] >= -3 and position[0] <= 3 and position[1] >= -3 and position[1] <= 3:
return True
else:
return False
...@@ -8,6 +8,17 @@ class Board: ...@@ -8,6 +8,17 @@ class Board:
self.colour = colour self.colour = colour
self.colours = []
if self.colour == 'red':
self.colours = ['red', 'green', 'blue']
elif self.colour == 'green':
self.colours = ['green', 'blue', 'red']
else:
self.colours = ['blue', 'red', 'green']
# List of exit tiles for each colour # List of exit tiles for each colour
self.exit_tiles = {'red':[(6,0), (6,1), (6,2), (6,3)], 'green':[(0,6),(1,6),(2,6),(3,6)],'blue':[(3,0),(2,1),(1,2),(0,3)]} self.exit_tiles = {'red':[(6,0), (6,1), (6,2), (6,3)], 'green':[(0,6),(1,6),(2,6),(3,6)],'blue':[(3,0),(2,1),(1,2),(0,3)]}
...@@ -105,8 +116,18 @@ class Board: ...@@ -105,8 +116,18 @@ class Board:
return (action[0], ((action[1][0][0]-3, action[1][0][1]-3), (action[1][1][0]-3, action[1][1][1]-3))) return (action[0], ((action[1][0][0]-3, action[1][0][1]-3), (action[1][1][0]-3, action[1][1][1]-3)))
def distance(self, start, end):
q1 = start[0]
q2 = end[0]
r1 = start[1]
r2 = end[1]
return (abs(q1 - q2) + abs(q1 + r1 - q2 - r2) + abs(r1 - r2))/2
def move(self, action): def move(self, action):
m_from = action[1][0]
m_to = action[1][1]
if action[0] == 'MOVE': if action[0] == 'MOVE':
piece = self.tiles[action[1][0][1]][action[1][0][0]] piece = self.tiles[action[1][0][1]][action[1][0][0]]
self.tiles[action[1][0][1]][action[1][0][0]] = None self.tiles[action[1][0][1]][action[1][0][0]] = None
...@@ -117,7 +138,6 @@ class Board: ...@@ -117,7 +138,6 @@ class Board:
piece = self.tiles[action[1][0][1]][action[1][0][0]] piece = self.tiles[action[1][0][1]][action[1][0][0]]
direction = (action[1][1][0]-action[1][0][0], action[1][1][1]-action[1][0][1]) direction = (action[1][1][0]-action[1][0][0], action[1][1][1]-action[1][0][1])
direction = (int(direction[0]/2), int(direction[1]/2)) direction = (int(direction[0]/2), int(direction[1]/2))
print("MID: " + str((piece.pos[0] + direction[0]-3, piece.pos[1] + direction[1]-3)))
mid_tile = (piece.pos[0] + direction[0], piece.pos[1] + direction[1]) mid_tile = (piece.pos[0] + direction[0], piece.pos[1] + direction[1])
taken_piece = self.tiles[mid_tile[1]][mid_tile[0]] taken_piece = self.tiles[mid_tile[1]][mid_tile[0]]
print(len(self.pieces[taken_piece.colour])) print(len(self.pieces[taken_piece.colour]))
...@@ -136,3 +156,43 @@ class Board: ...@@ -136,3 +156,43 @@ class Board:
piece = self.tiles[action[1][1]][action[1][0]] piece = self.tiles[action[1][1]][action[1][0]]
self.tiles[action[1][1]][action[1][0]] = None self.tiles[action[1][1]][action[1][0]] = None
self.pieces[piece.colour].remove(piece) self.pieces[piece.colour].remove(piece)
def undo_move(self, move, colour):
move_from = move[1][1]
move_to = move[1][0]
if move[0] == 'MOVE':
shift_piece(move_from, move_to)
elif move[0] == 'JUMP':
piece = self.tiles[move_from[1]][move_from[0]]
direction = move_direction(move_from,move_to)
mid_tile = (piece.pos[0] + direction[0], piece.pos[1] + direction[1])
capture_piece(mid_tile, self.tiles[mid_tile[1]][mid_tile[0]])
shift_piece(move_from, move_to)
elif move[0] == 'EXIT':
piece = Piece.Piece(move[1], colour)
self.tiles[move[1][1]][move[1][0]] = piece
self.pieces[piece.colour].append(piece)
def capture_piece(self, pos, colour):
taken_piece = self.tiles[pos[1]][pos[0]]
for i in range(len(self.pieces[taken_piece.colour])):
if self.pieces[taken_piece.colour][i] is taken_piece:
self.pieces[taken_piece.colour].pop(i)
self.pieces[colour].append(taken_piece)
taken_piece.colour = colour
break
def shift_piece(self, t_from, t_to):
piece = self.tiles[t_from[1]][t_from[0]]
self.tiles[t_from[1]][t_from[0]] = None
self.tiles[t_to[1]][t_to[0]] = piece
piece.pos = t_to
def move_direction(move_from, move_to):
direction = (move_to[0]-move_from[0], move_to[1]-move_from[1])
return (int(direction[0]/2), int(direction[1]/2))
No preview for this file type
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment