add weighted movement for ai, so it'll intentionally capture things
This commit is contained in:
parent
da75e49e23
commit
43faa277bb
1 changed files with 132 additions and 40 deletions
172
Main.gd
172
Main.gd
|
@ -81,56 +81,148 @@ 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:
|
||||
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
|
||||
else:
|
||||
continue
|
||||
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:
|
||||
#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:
|
||||
p_board[i][k] = 0
|
||||
return p_board
|
||||
|
||||
func new_turn():
|
||||
check_for_promotion()
|
||||
var text_board = board_to_text_board(board)
|
||||
|
|
Loading…
Reference in a new issue