-
Notifications
You must be signed in to change notification settings - Fork 0
/
GroupL_AI.py
170 lines (138 loc) · 5.61 KB
/
GroupL_AI.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
#!/usr/bin/env python3
# -*- coding: utf-8 -*
"""
COMS W4701 Artificial Intelligence - Programming Homework 2
An AI player for Othello. This is the template file that you need to
complete and submit.
@author: Armaan Bassi, Suwei Ma, Yuval Vaknin
"""
import random
import sys
import time
import math
# You can use the functions in othello_shared to write your AI
from othello_shared import find_lines, get_possible_moves, get_score, play_move
def compute_utility(board, color):
score = get_score(board)
#returns tuple (# of dark disks, # of light disks)
if color == 1:
return score[0]-score[1]
else:
return score[1]-score[0]
############ MINIMAX ###############################
seen = set();
def minimax_min_node(board, color, DEPTH_LIMIT, depth, ab):
if board in seen:
return ab;
else:
seen.add(board);
opp_color = 1 if color == 2 else 2
possible_moves = get_possible_moves(board, opp_color)
if depth >= DEPTH_LIMIT:
return compute_utility(board, color) # Or compute a different heuristic function
if not possible_moves:
return compute_utility(board, color)
best_move = None
best_score = math.inf
for move in possible_moves:
new_board = play_move(board, opp_color, move[0], move[1])
score = minimax_max_node(new_board, color, DEPTH_LIMIT, depth+1, best_score)
if score < best_score:
best_move = move
best_score = score
if move == (7,7) or move == (0,0) or move == (7,0) or move == (0,7):
best_score -= 2
if move==(1,0) or move==(1,1) or move==(0,1) or move==(6,0) or move==(6,1) or move==(7,1) or move==(0,6) or move==(1,6) or move==(1,7) or move==(6,7) or move==(6,6) or move==(7,6):
best_score += 2
if best_score < ab:
return ab
return best_score
def minimax_max_node(board, color, DEPTH_LIMIT, depth, ab):
if board in seen:
return ab;
else:
seen.add(board);
possible_moves = get_possible_moves(board, color)
if depth >= DEPTH_LIMIT:
return compute_utility(board, color) # Or compute a different heuristic function
if not possible_moves:
return compute_utility(board, color)
best_move = None
best_score = -math.inf
for move in possible_moves:
new_board = play_move(board, color, move[0], move[1])
score = minimax_min_node(new_board, color, DEPTH_LIMIT, depth+1, best_score)
if score > best_score:
best_move = move
best_score = score
if move == (7,7) or move == (0,0) or move == (7,0) or move == (0,7):
best_score += 4
if move==(1,0) or move==(1,1) or move==(0,1) or move==(6,0) or move==(6,1) or move==(7,1) or move==(0,6) or move==(1,6) or move==(1,7) or move==(6,7) or move==(6,6) or move==(7,6):
best_score -= 2
if best_score > ab:
return ab
return best_score
def select_move_minimax(board, color):
global seen;
seen = set()
"""
Given a board and a player color, decide on a move.
The return value is a tuple of integers (i,j), where
i is the column and j is the row on the board.
"""
#move = tuple --> (COLUMN, ROW)
#play_move(board, color, move)
DEPTH_LIMIT = 4
possible_moves = get_possible_moves(board, color)
best_move = None
best_score = -math.inf
for move in possible_moves:
new_board = play_move(board, color, move[0], move[1])
score = minimax_min_node(new_board, color, DEPTH_LIMIT, 0, best_score)
if score > best_score:
best_move = move
best_score = score
return best_move
############ ALPHA-BETA PRUNING #####################
#alphabeta_min_node(board, color, alpha, beta, level, limit)
def alphabeta_min_node(board, color, alpha, beta):
return None
#alphabeta_max_node(board, color, alpha, beta, level, limit)
def alphabeta_max_node(board, color, alpha, beta):
return None
def select_move_alphabeta(board, color):
return 0,0
####################################################
def run_ai():
"""
This function establishes communication with the game manager.
It first introduces itself and receives its color.
Then it repeatedly receives the current score and current board state
until the game is over.
"""
print("Othello AI") # First line is the name of this AI
color = int(input()) # Then we read the color: 1 for dark (goes first),
# 2 for light.
while True: # This is the main loop
# Read in the current game status, for example:
# "SCORE 2 2" or "FINAL 33 31" if the game is over.
# The first number is the score for player 1 (dark), the second for player 2 (light)
next_input = input()
status, dark_score_s, light_score_s = next_input.strip().split()
dark_score = int(dark_score_s)
light_score = int(light_score_s)
if status == "FINAL": # Game is over.
print
else:
board = eval(input()) # Read in the input and turn it into a Python
# object. The format is a list of rows. The
# squares in each row are represented by
# 0 : empty square
# 1 : dark disk (player 1)
# 2 : light disk (player 2)
# Select the move and send it to the manager
movei, movej = select_move_minimax(board, color)
#movei, movej = select_move_alphabeta(board, color)
print("{} {}".format(movei, movej))
if __name__ == "__main__":
run_ai()