add ai movement based on 'points' gained/lost
This commit is contained in:
parent
265b50e1de
commit
fb3f5d1394
2 changed files with 139 additions and 27 deletions
158
Main.gd
158
Main.gd
|
@ -34,13 +34,18 @@ var team2 = 2
|
|||
|
||||
func _ready():
|
||||
make_player1("green")
|
||||
make_player2("red")
|
||||
#make_player2("red")
|
||||
|
||||
#checkmatet1()
|
||||
#checkmatet2()
|
||||
#spawn_piece("pawn", "teal", 2, 6, team1)
|
||||
#spawn_piece("pawn", "red", 3, 4, team2)
|
||||
#spawn_piece("rook", "red", 0, 5, team2)
|
||||
#spawn_piece("pawn", "teal", 2, 1, team1)
|
||||
#spawn_piece("knight", "teal", 4, 6, team1)
|
||||
#spawn_piece("knight", "teal", 5, 4, team1)
|
||||
#spawn_piece("rook", "teal", 7, 6, team1)
|
||||
|
||||
#spawn_piece("queen", "red", 3, 5, team2)
|
||||
#spawn_piece("pawn", "red", 7, 1, team2)
|
||||
|
||||
var captures = update_capture_tables(board_to_text_board(board))
|
||||
team1_capture = captures[0]
|
||||
|
@ -73,10 +78,18 @@ func _process(_delta):
|
|||
if click_spot() == Vector2(0,0):
|
||||
print(history)
|
||||
if click_spot() == Vector2(1,0):
|
||||
print("Queuing for team2...")
|
||||
ai_move(team2, board_to_text_board(board), ai_modes.points, 1)
|
||||
if click_spot() == Vector2(1,1):
|
||||
print("Killing pawn: %s" % [evaluate_move([3,5], [2,6], board_to_text_board(board), team2, 1)])
|
||||
print("Killing knight: %s" % [evaluate_move([3,5], [4,6], board_to_text_board(board), team2, 1)])
|
||||
print("Going to (3,1): %s" % [evaluate_move([3,5], [3,1], board_to_text_board(board), team2, 1)])
|
||||
print("Going to (3,4) (enemy controlled): %s" % [evaluate_move([3,5], [3,4], board_to_text_board(board), team2, 1)])
|
||||
if click_spot() == Vector2(1,2):
|
||||
#print(team2_every_legal_move(board_to_text_board(board)))
|
||||
print("whoops")
|
||||
if click_spot() == Vector2(2,0):
|
||||
print(board_to_text_board(board))
|
||||
print("Queuing for team1...")
|
||||
ai_move(team1, board_to_text_board(board), ai_modes.points, 1)
|
||||
#print("Killing queen: %s" % evaluate_move([2,6], [3,5], board_to_text_board(board), team1, 1))
|
||||
if click_spot() == Vector2(4,0):
|
||||
color_tiles(team2_capture, "red")
|
||||
if click_spot() == Vector2(5,0):
|
||||
|
@ -93,7 +106,7 @@ func _process(_delta):
|
|||
enum ai_modes {
|
||||
purely_random,
|
||||
weighted_random,
|
||||
minimax_depth_2,
|
||||
points,
|
||||
}
|
||||
|
||||
var ai_weights = {
|
||||
|
@ -101,30 +114,110 @@ var ai_weights = {
|
|||
knight = 30,
|
||||
bishop = 30,
|
||||
rook = 50,
|
||||
queen = 80,
|
||||
queen = 500,
|
||||
king = 1000,
|
||||
}
|
||||
|
||||
func ai_move(team, text_board, ai_mode=ai_modes.purely_random):
|
||||
func ai_move(team, text_board, ai_mode=ai_modes.purely_random, depth=1):
|
||||
var legal_every_move = team_every_legal_move(text_board, team)
|
||||
var the_move
|
||||
if ai_mode == ai_modes.purely_random:
|
||||
ai_random_move(legal_every_move)
|
||||
the_move = ai_random_move(team, text_board, legal_every_move)
|
||||
elif ai_mode == ai_modes.weighted_random:
|
||||
ai_weighted_random(team, text_board, legal_every_move)
|
||||
elif ai_mode == ai_modes.minimax_depth_2:
|
||||
ai_minimax_depth_2(team, text_board, legal_every_move)
|
||||
the_move = ai_weighted_random(team, text_board, legal_every_move)
|
||||
elif ai_mode == ai_modes.points:
|
||||
the_move = ai_points_system(team, legal_every_move, text_board, depth)
|
||||
#print(the_move)
|
||||
if the_move:
|
||||
if the_move[1]:
|
||||
ai_make_move(the_move[1], the_move[2])
|
||||
new_turn()
|
||||
|
||||
func ai_minimax_depth_2(team, text_board, legal_every_move):
|
||||
pass
|
||||
func ai_points_system(team, legal_moves, text_board, depth=2):
|
||||
var best = [-INF, null]
|
||||
var alpha = -INF
|
||||
var beta = -INF
|
||||
legal_moves.shuffle()
|
||||
for every_moves in legal_moves:
|
||||
var piece = every_moves[0]
|
||||
var moves = every_moves[1]
|
||||
for move in moves:
|
||||
var eval = evaluate_move(piece, move, text_board, team, depth)
|
||||
#var eval = eval_move2(piece, move, text_board, team, depth)
|
||||
if eval > best[0]:
|
||||
best = [eval, piece, move]
|
||||
print("This move is worth: %s" % best[0])
|
||||
return best
|
||||
|
||||
func evaluate_move(piece, move, text_board, team, depth, add_points=false):
|
||||
var p_board = generate_points_board(team, text_board)
|
||||
var points = p_board[move[0]][move[1]]
|
||||
if depth == 0 or depth <= 0:
|
||||
return points
|
||||
|
||||
# evaluate opposing team now
|
||||
var eval_board
|
||||
eval_board = ai_text_board_move(text_board.duplicate(true), piece, move)
|
||||
var legal_moves
|
||||
if team == team1:
|
||||
legal_moves = team_every_legal_move(eval_board, team2)
|
||||
else: # team2
|
||||
legal_moves = team_every_legal_move(eval_board, team1)
|
||||
var highest_opposing_points = 0
|
||||
for every_moves in legal_moves:
|
||||
var this_piece = every_moves[0]
|
||||
for this_move in every_moves[1]:
|
||||
var eval
|
||||
if team == team1:
|
||||
eval = evaluate_move(this_piece, this_move, eval_board.duplicate(true), team2, depth-1, !add_points)
|
||||
else: # team2
|
||||
eval = evaluate_move(this_piece, this_move, eval_board.duplicate(true), team1, depth-1, !add_points)
|
||||
if eval > highest_opposing_points:
|
||||
#rint("Piece at (%s) moves to (%s), gaining %s points" % [this_piece, this_move, eval])
|
||||
highest_opposing_points = eval
|
||||
if add_points:
|
||||
points += highest_opposing_points
|
||||
else:
|
||||
points -= highest_opposing_points
|
||||
|
||||
return points
|
||||
|
||||
func ai_text_board_move(text_board, piece, move):
|
||||
var new_board = text_board.duplicate(true)
|
||||
var pos = new_board[piece[0]][piece[1]]
|
||||
pos[text_board_ele.has_moved] = true
|
||||
new_board[move[0]][move[1]] = pos
|
||||
new_board[piece[0]][piece[1]] = 0
|
||||
|
||||
if move.size() == 3:
|
||||
#rint(new_board[move[0]][move[1] - 1])
|
||||
if move[2] == movement_condition.en_passant_kill:
|
||||
if move[1] + 1 < 8 and new_board[move[0]][move[1] + 1] is Array and new_board[move[0]][move[1] + 1][text_board_ele.en_passant]:
|
||||
new_board[ move[0] ][(move[1] + 1)] = 0
|
||||
elif move[1] - 1 > 0 and new_board[move[0]][(move[1] - 1)] is Array and new_board[move[0]][move[1] - 1][text_board_ele.en_passant]:
|
||||
new_board [move[0] ][(move[1] - 1)] = 0
|
||||
elif move[2] == movement_condition.king_side_castling:
|
||||
# TODO hard coding rook positions like this seems bad
|
||||
var rook = new_board[7][pos[1]]
|
||||
new_board[5][pos[1]] = rook
|
||||
new_board[7][pos[1]] = 0
|
||||
elif move[2] == movement_condition.queen_side_castling:
|
||||
# TODO hard coding rook positions like this seems bad
|
||||
var rook = new_board[0][pos[1]]
|
||||
new_board[3][pos[1]] = rook
|
||||
new_board[0][pos[1]] = 0
|
||||
return new_board
|
||||
|
||||
func ai_make_move(piece, move):
|
||||
#rint(piece)
|
||||
#rint(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[move[0]][move[1]].has_moved = true
|
||||
board[pos[0]][pos[1]] = 0
|
||||
|
||||
if move.size() == 3:
|
||||
|
@ -143,7 +236,7 @@ func ai_make_move(piece, move):
|
|||
board[3][pos[1]] = board[0][pos[1]]
|
||||
board[0][pos[1]] = 0
|
||||
|
||||
func ai_random_move(legal_every_move):
|
||||
func ai_random_move(team, text_board, legal_every_move):
|
||||
legal_every_move.shuffle()
|
||||
while 1:
|
||||
var piece_and_moves = legal_every_move.pop_back()
|
||||
|
@ -156,16 +249,14 @@ func ai_random_move(legal_every_move):
|
|||
#rint(moves)
|
||||
moves.shuffle()
|
||||
var move = moves.pop_back()
|
||||
ai_make_move(piece, move)
|
||||
return
|
||||
#rint( ai_text_board_move(board_to_text_board(board), piece, move) )
|
||||
#ai_make_move(piece, move)
|
||||
var p_board = generate_points_board(team, text_board)
|
||||
return [p_board[move[0]][move[1]], piece, move]
|
||||
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)
|
||||
func get_moves_with_points(p_board, legal_every_move):
|
||||
var saved_moves = []
|
||||
for every_move in legal_every_move:
|
||||
var piece = every_move[0]
|
||||
|
@ -180,15 +271,28 @@ func ai_weighted_random(team, text_board, legal_every_move):
|
|||
saved_moves.append([p_board[move[0]][move[1]], piece, move])
|
||||
else:
|
||||
continue
|
||||
return saved_moves
|
||||
|
||||
func ai_weighted_random(team, text_board, legal_every_move, dict = {"no_shuffle":false, "skip_amount":0}):
|
||||
# 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 = get_moves_with_points(p_board, legal_every_move)
|
||||
if saved_moves.size() > 0:
|
||||
saved_moves.shuffle()
|
||||
if ! dict.get("no_shuffle"):
|
||||
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])
|
||||
var the_move
|
||||
the_move = saved_moves.pop_back()
|
||||
for i in dict.get("skip_amount"):
|
||||
the_move = saved_moves.pop_back()
|
||||
#ai_make_move(the_move[1], the_move[2])
|
||||
return the_move
|
||||
else:
|
||||
ai_random_move(legal_every_move)
|
||||
return ai_random_move(team, text_board, legal_every_move)
|
||||
|
||||
func sort_ascending(a, b):
|
||||
if a[0] < b[0]:
|
||||
|
|
|
@ -34,6 +34,10 @@ window/stretch/aspect="expand"
|
|||
|
||||
singletons=[ "res://addons/godot-git-plugin/git_api.gdnlib" ]
|
||||
|
||||
[global]
|
||||
|
||||
limit=false
|
||||
|
||||
[input]
|
||||
|
||||
mouse1={
|
||||
|
@ -47,6 +51,10 @@ mouse2={
|
|||
]
|
||||
}
|
||||
|
||||
[network]
|
||||
|
||||
limits/debugger_stdout/max_chars_per_second=9999999999
|
||||
|
||||
[physics]
|
||||
|
||||
common/enable_pause_aware_picking=true
|
||||
|
|
Loading…
Reference in a new issue