-
Notifications
You must be signed in to change notification settings - Fork 3
/
PlayerAI1.py
163 lines (156 loc) · 6 KB
/
PlayerAI1.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
# -*- coding: utf-8 -*-
"""
Created on Mon Mar 30 22:18:10 2020
@author: WIKI
"""
import pygame, sys, random
from pygame.locals import *
from Piece import Piece
from copy import copy, deepcopy
from MINIMAX_AI import PlayerMINMAX
import sqlite3
# this AI is based only on the experience of many games database that were played by expert players
class PlayerAI1():
def __init__(self,pieces,clicked_piece = 1,displayed_moves = [],eat_moves=[],completethemove=False):
self.clicked_piece = clicked_piece
self.pieces = pieces
self.displayed_moves = displayed_moves
self.eat_moves = []
self.completethemove = completethemove
self.conn = sqlite3.connect("Training_database/training.db")
self.c=self.conn.cursor()
def __copy__(self):
return type(self)(self.pieces,self.clicked_piece,self.displayed_moves,self.eat_moves,self.completethemove)
def __deepcopy__(self, memo): # memo is a dict of id's to copies
id_self = id(self) # memoization avoids unnecesary recursion
_copy = memo.get(id_self)
if _copy is None:
_copy = type(self)(
deepcopy(self.pieces,memo),
deepcopy(self.clicked_piece,memo),
deepcopy(self.displayed_moves,memo),
deepcopy(self.eat_moves,memo),
deepcopy(self.completethemove,memo))
memo[id_self] = _copy
return _copy
def human_intervention(self,table):
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
elif event.type == pygame.MOUSEBUTTONDOWN:
pos = pygame.mouse.get_pos()
if 1101 > pos[0] > 1050 and 526 > pos[1] > 475:
table.undo()
return False
if 1100 > pos[0] > 900 and 650 > pos[1] > 600:
self.conn.close()
table.FPS = 60
table.menu()
return False
def get(self,xx,yy):
cnt = 0
for x in range(8):
for y in range(8):
if (x+y)%2==1:
cnt+=1
if(x==yy and y == xx):
return 33-cnt
def hash(self,board):
ret=""
for i in range(32):
ret+='e'
L = list(ret)
for piece in board.pieces:
x = (piece.x-10)//board.BOXWIDTH
y = (piece.y-10)//board.BOXHEIGHT
wa = self.get(x,y)-1
L[wa]=piece.color[0]
if piece.king == True:
L[wa] = L[wa].upper()
L.reverse()
ret = "".join(L)
return ret
def search_the_move(self,mv,c,moves,piece,xx,yy,board):
From = self.get(xx,yy)
To = self.get(mv[0],mv[1])
m = str(From)+c+str(To)
self.c.execute("""SELECT gain FROM visited where state=? AND move=?""",(self.hash(board),m))
wa = self.c.fetchone()
if wa!=None :
moves.append((mv,piece))
def go(self,pieces,board,otherplayer,table):
ok = self.human_intervention(table)
if ok == False:
return False
ok = False
move = None
moves = []
for piece in pieces:
L = piece.display_possible_moves(board)
xx = (piece.x-10)//board.BOXWIDTH
yy = (piece.y-10)//board.BOXHEIGHT
for mv in L:
self.search_the_move(mv,'_',moves,piece,xx,yy,board)
self.search_the_move(mv,'x',moves,piece,xx,yy,board)
if len(moves) == 0:
cp = self.completethemove
if self.pieces[0].color == 'white':
table.player1 = PlayerMINMAX(table.board.whitepieces)
table.player1.completethemove = cp
else:
table.player2 = PlayerMINMAX(table.board.blackpieces)
table.player2.completethemove = cp
print('on my own')
return False
self.clicked_piece = random.choice(pieces)
move = random.choice(self.clicked_piece.display_possible_moves(table.board))
else:
p = random.choice(moves)
move,self.clicked_piece = p[0],p[1]
x = move[0]
y = move[1]
xx = (self.clicked_piece.x-10)//board.BOXWIDTH
yy = (self.clicked_piece.y-10)//board.BOXHEIGHT
if abs(xx-x) == 2 and abs(yy-y) == 2:
i = x-xx
j = y-yy
if i<0:
i+=1
else:
i-=1
if j<0:
j+=1
else:
j-=1
piece = self.pieces[0].who_is_there(xx+i,yy+j,table.board)
otherplayer.pieces.remove(piece)
table.board.pieces.remove(piece)
ok = True
wasking = self.clicked_piece.king
self.clicked_piece.update(x*board.BOXWIDTH + 10,y*board.BOXHEIGHT + 10,board)
if(not (len(self.clicked_piece.can_eat(board))==0 or ok == False) and (wasking == self.clicked_piece.king)):
self.completethemove = True
else:
self.completethemove = False
return (len(self.clicked_piece.can_eat(board))==0 or ok == False) or (wasking != self.clicked_piece.king)
def should_eat(self,board):
L = []
for piece in self.pieces:
if len(piece.can_eat(board))>0:
L.append(piece)
return L
def make_a_move(self,table,states_visited = None):
L = []
otherplayer = table.player1 if self.pieces[0].color =='black' else table.player2
if(self.completethemove == True):
L.append(self.clicked_piece)
else:
L = self.should_eat(table.board)
if len(L)>0:
return self.go(L,table.board,otherplayer,table)
else:
for piece in self.pieces:
if len(piece.display_possible_moves(table.board))>0:
L.append(piece)
return self.go(L,table.board,otherplayer,table)