summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Main.gd170
1 files changed, 131 insertions, 39 deletions
diff --git a/Main.gd b/Main.gd
index 82146c8..ea47a80 100644
--- a/Main.gd
+++ b/Main.gd
@@ -81,55 +81,147 @@ func _process(_delta):
ai_move(team2, board_to_text_board(board))
if click_spot() == Vector2(7,1):
ai_move(team1, board_to_text_board(board))
+ if click_spot() == Vector2(6,0):
+ ai_move(team2, board_to_text_board(board), ai_modes.weighted_random)
+ if click_spot() == Vector2(6,1):
+ ai_move(team1, board_to_text_board(board), ai_modes.weighted_random)
enum ai_modes {
purely_random,
+ weighted_random,
+ minimax_depth_2,
+}
+
+var ai_weights = {
+ pawn = 10,
+ knight = 30,
+ bishop = 30,
+ rook = 50,
+ queen = 80,
+ king = 1000,
}
func ai_move(team, text_board, ai_mode=ai_modes.purely_random):
var legal_every_move = team_every_legal_move(text_board, team)
- legal_every_move.shuffle()
if ai_mode == ai_modes.purely_random:
- while 1:
- var piece_and_moves = legal_every_move.pop_back()
- if piece_and_moves:
- pass
- else:
+ ai_random_move(legal_every_move)
+ elif ai_mode == ai_modes.weighted_random:
+ ai_weighted_random(team, text_board, legal_every_move)
+ new_turn()
+
+func ai_make_move(piece, move):
+ var pos = position_to_board_cell(Vector2(piece[0] * board_cell, piece[1] * board_cell))
+ var board_piece = board[pos[0]][pos[1]]
+ board_piece.position = in_square(Vector2(move[0] * board_cell, move[1] * board_cell))
+ if board[move[0]][move[1]]:
+ board[move[0]][move[1]].kill()
+ board[move[0]][move[1]] = board_piece
+ board[pos[0]][pos[1]] = 0
+
+ if move.size() == 3:
+ if move[2] == movement_condition.en_passant_kill:
+ kill_en_passant_pawn([move[0], move[1]])
+ elif move[2] == movement_condition.king_side_castling:
+ # TODO hard coding rook positions like this seems bad
+ var rook = board[7][pos[1]]
+ rook.position = in_square(Vector2(5 * board_cell, pos[1] * board_cell))
+ board[5][pos[1]] = board[7][pos[1]]
+ board[7][pos[1]] = 0
+ elif move[2] == movement_condition.queen_side_castling:
+ # TODO hard coding rook positions like this seems bad
+ var rook = board[0][pos[1]]
+ rook.position = in_square(Vector2(3 * board_cell, pos[1] * board_cell))
+ board[3][pos[1]] = board[0][pos[1]]
+ board[0][pos[1]] = 0
+
+func ai_random_move(legal_every_move):
+ legal_every_move.shuffle()
+ while 1:
+ var piece_and_moves = legal_every_move.pop_back()
+ if ! piece_and_moves:
+ if ! legal_every_move:
break # AI literally cannot move this turn, game should be offically over before this occurs
- var piece = piece_and_moves[0]
- var moves = piece_and_moves[1]
- if moves:
- print(moves)
- moves.shuffle()
- var move = moves.pop_back()
- var pos = position_to_board_cell(Vector2(piece[0] * board_cell, piece[1] * board_cell))
- var board_piece = board[pos[0]][pos[1]]
- board_piece.position = in_square(Vector2(move[0] * board_cell, move[1] * board_cell))
- if board[move[0]][move[1]]:
- board[move[0]][move[1]].kill()
- board[move[0]][move[1]] = board_piece
- board[pos[0]][pos[1]] = 0
-
- if move.size() == 3:
- if move[2] == movement_condition.en_passant_kill:
- kill_en_passant_pawn([move[0], move[1]])
- elif move[2] == movement_condition.king_side_castling:
- # TODO hard coding rook positions like this seems bad
- var rook = board[7][pos[1]]
- rook.position = in_square(Vector2(5 * board_cell, pos[1] * board_cell))
- board[5][pos[1]] = board[7][pos[1]]
- board[7][pos[1]] = 0
- elif move[2] == movement_condition.queen_side_castling:
- # TODO hard coding rook positions like this seems bad
- var rook = board[0][pos[1]]
- rook.position = in_square(Vector2(3 * board_cell, pos[1] * board_cell))
- board[3][pos[1]] = board[0][pos[1]]
- board[0][pos[1]] = 0
- #print("piece at (%s,%s), to (%s,%s)" % [ piece[0], piece[1], move[0], move[1] ])
- break
+ var piece = piece_and_moves[0]
+ var moves = piece_and_moves[1]
+ if moves:
+ #rint(moves)
+ moves.shuffle()
+ var move = moves.pop_back()
+ ai_make_move(piece, move)
+ return
+ else:
+ continue
+
+func ai_weighted_random(team, text_board, legal_every_move):
+ # generate a board with 'points' on it.
+ # if move[x],move[y] corrispond over some points keep the move in memory. then, sort move by smallest to greatest points
+ # pop_back() to get 'best move'. if there are no moves, just do random movement.
+ var p_board = generate_points_board(team, text_board)
+ var saved_moves = []
+ for every_move in legal_every_move:
+ var piece = every_move[0]
+ var moves = every_move[1]
+ if moves:
+ for move in moves:
+ if p_board[move[0]][move[1]] > 0:
+ saved_moves.append([p_board[move[0]][move[1]], piece, move])
+ else:
+ continue
+ if saved_moves.size() > 0:
+ saved_moves.shuffle()
+ #rint(saved_moves)
+ saved_moves.sort_custom(self, "sort_ascending") # sort, by smallest to greatest, then pop_back()
+ print(saved_moves)
+ var the_move = saved_moves.pop_back()
+ ai_make_move(the_move[1], the_move[2])
+ else:
+ ai_random_move(legal_every_move)
+
+func sort_ascending(a, b):
+ if a[0] < b[0]:
+ return true
+ return false
+
+func generate_points_board(team, text_board):
+ var p_board = new_board()
+ for i in 8:
+ for k in 8:
+ var piece = text_board[i][k]
+ if piece:
+ match piece[0]:
+ piece_names.pawn:
+ if piece[1] == team:
+ p_board[i][k] = -1 * ai_weights.pawn
+ else:
+ p_board[i][k] = ai_weights.pawn
+ piece_names.rook:
+ if piece[1] == team:
+ p_board[i][k] = -1 * ai_weights.rook
+ else:
+ p_board[i][k] = ai_weights.rook
+ piece_names.knight:
+ if piece[1] == team:
+ p_board[i][k] = -1 * ai_weights.knight
+ else:
+ p_board[i][k] = ai_weights.knight
+ piece_names.bishop:
+ if piece[1] == team:
+ p_board[i][k] = -1 * ai_weights.bishop
+ else:
+ p_board[i][k] = ai_weights.bishop
+ piece_names.queen:
+ if piece[1] == team:
+ p_board[i][k] = -1 * ai_weights.queen
+ else:
+ p_board[i][k] = ai_weights.queen
+ piece_names.king:
+ if piece[1] == team:
+ p_board[i][k] = -1 * ai_weights.king
+ else:
+ p_board[i][k] = ai_weights.king
else:
- continue
- new_turn()
+ p_board[i][k] = 0
+ return p_board
func new_turn():
check_for_promotion()