from math import*
import random
a1 = 3 #these numbers will be used to check spots and if mills formed.
a3 = 4 #numbers start at 3 because 1 and 2 will be assigned to spots for each player
a5 = 5
b2 = 6
b3 = 7
b4 = 8
c1 = 9
c2 = 10
c4 = 11
c5 = 12
d2 = 13
d3 = 14
d4 = 15
e1 = 16
e3 = 17
e5 = 18
def main():
CheckArray = [a1,a3,a5,b2,b3,b4,c1,c2,c4,c5,d2,d3,d4,e1,e3,e5] #first array of all spots
OCheckArray = [a1,a3,a5,b2,b3,b4,c1,c2,c4,c5,d2,d3,d4,e1,e3,e5] #original array for comparison in changing
Futureboard = [a1,a3,a5,b2,b3,b4,c1,c2,c4,c5,d2,d3,d4,e1,e3,e5]
MillArray = [[0,a1,a3,a5],[0,b2,b3,b4],[0,a1,c1,e1],[0,b2,c2,d2],[0,b4,c4,d4],[0,a5,c5,e5],[0,d2,d3,d4],[0,e1,e3,e5]] #Array to check mills
FutureMill = [[0,a1,a3,a5],[0,b2,b3,b4],[0,a1,c1,e1],[0,b2,c2,d2],[0,b4,c4,d4],[0,a5,c5,e5],[0,d2,d3,d4],[0,e1,e3,e5]]
OMillArray = [[0,a1,a3,a5],[0,b2,b3,b4],[0,a1,c1,e1],[0,b2,c2,d2],[0,b4,c4,d4],[0,a5,c5,e5],[0,d2,d3,d4],[0,e1,e3,e5]]
ConnectArray = [[a1,a3,c1,0], [a3,a1,a5,b3],[a5,a3,c5,0], [b2,c2,b3,0], [b3,b2,b4,a3], [b4,b3,c4,0], [c1,c2,a1,e1], [c2,c1,b2,d2], #Array to check connections
[c4,c5,b4,d4],[c5,c4,a5,e5], [d2,d3,c2,0], [d3,d2,d4,e3], [d4,d3,c4,0], [e1,c1,e3,0], [e3,e1,e5,d3], [e5,e3,c5,0]]
p1win = 0
p2win = 0
def RandOpenNum(Legal): #Input Legal array. This will check how many elements in legal array
counter = 0
YES = True
while (YES == True):
if (Legal[counter] != 0):
counter = counter+1
if (counter == 16):
YES = False
else:
YES = False
counter = counter-1
return counter
def LegalChoices(turn): #Creates an array of legal choices for whomevers turn it is
LegalPlacement = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
counter = 0
Number = 0
while (counter<16): #Campares to CheckArray to see which spots open
if (CheckArray[counter] == 1 or CheckArray[counter] == 2):
counter = counter+1
else:
LegalPlacement[Number] = CheckArray[counter]
counter = counter+1
Number = Number+1
return LegalPlacement
def LegalMove(turn,other): #function to determine legal moves during second stage
Moves = [[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]]
counter = 0
ticker1 = 0
#the following while loops determine pieces that can move and to which spot and places it in the Moves matrix
#the first row of the moves array contains the piece that can move
#the second array contains where that piece can move
while (ticker1 < 16):
ticker2 = 0
while (ticker2<16):
if (ConnectArray[ticker1][0] == OCheckArray[ticker2]):
if (CheckArray[ticker2] == turn):
ticker3 = 1
while (ticker3<4):
ticker4 = 0
while (ticker4<16):
if (ConnectArray[ticker1][ticker3] == CheckArray[ticker4]):
Moves[0][counter] = ConnectArray[ticker1][0]
Moves[1][counter] = ConnectArray[ticker1][ticker3]
counter = counter+1
ticker4 = 16
else:
ticker4 = ticker4+1
ticker3 = ticker3+1
ticker2 = 16
else:
ticker2 = 0
ticker1 = ticker1+1
if (ticker1 == 16):
ticker2 = 16
else:
ticker2 = ticker2+1
ticker1 = ticker1+1
return Moves # returns the array
def LegalRemove(other): #Creates array to determine which pieces can be removed
LegalRemoval = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
counter = 0
Number = 0
while (counter<16):
if (CheckArray[counter] == other):
LegalRemoval[Number] = OCheckArray[counter]
counter = counter+1
Number = Number+1
else:
counter = counter+1
return LegalRemoval
def ChangeOpening(counter, turn, array, Millarray):
array[counter] = turn
ticker1 = 0
while (ticker1<8):
ticker2 = 1
while (ticker2<4):
if (OCheckArray[counter] == Millarray[ticker1][ticker2]):
Millarray[ticker1][ticker2] = turn
else:
ticker2 = ticker2+1
ticker1 = ticker1+1
NewMill = 0
ticker1 = 0
while (ticker1<8):
if (Millarray[ticker1][1] == Millarray[ticker1][2] and Millarray[ticker1][1] == Millarray[ticker1][3]):
if (Millarray[ticker1][0] != 30):
Millarray[ticker1][0] = 30
NewMill = 1
ticker1 = ticker1+1
else:
ticker1 = ticker1+1
else:
ticker1 = ticker1+1
return NewMill #returns if a New Mill is formed
def ReverseOpening(counter, array, millarray): # if a piece is removed, updates the arrays
array[counter] = OCheckArray[counter]
ticker1 = 0
while (ticker1<8):
ticker2 = 1
while (ticker2<4):
if (OCheckArray[counter] == OMillArray[ticker1][ticker2]):
millarray[ticker1][ticker2] = OMillArray[ticker1][ticker2]
ticker2 = ticker2+1
if (millarray[ticker1][0] == 30):
millarray[ticker1][0] = 0
else:
ticker2 = ticker2+1
ticker1 = ticker1+1
#Function to reverse future move
def ReverseFutureMove():
counter = 0
while (counter < 16):
Futureboard[counter] = CheckArray[counter]
counter = counter + 1
ticker1 = 0
while (ticker1<8):
ticker2 = 1
while (ticker2<4):
FutureMill[ticker1][ticker2] = MillArray[ticker1][ticker2]
ticker2 = ticker2+1
ticker1 = ticker1+1
def Scoring(piece, playpiece, score):
millmade = ChangeOpening(piece, turn, Futureboard, FutureMill)
if (millmade == 1):
score = score + 5
count1 = 0
while (count1<8): #Finds if a mill is being setup for the player
if (MillArray[count1][1] == playpiece):
if (FutureMill[count1][1] == turn):
if (FutureMill[count1][2] == turn and FutureMill[count1][3] > 2):
score = score + 2
if (FutureMill[count1][3] == turn and FutureMill[count1][2] > 2):
score = score + 2
if (MillArray[count1][2] == playpiece):
if (FutureMill[count1][2] == turn):
if (FutureMill[count1][1] == turn and FutureMill[count1][3] > 2):
score = score + 2
if (FutureMill[count1][3] == turn and FutureMill[count1][1] > 2):
score = score + 2
if (MillArray[count1][3] == playpiece):
if (FutureMill[count1][3] == turn):
if (FutureMill[count1][1] == turn and FutureMill[count1][2] > 2):
score = score + 2
if (FutureMill[count1][2] == turn and FutureMill[count1][1] > 2):
score = score + 2
count1 = count1 + 1
count2 = 0
while (count2<8): #Finds if opponent's mill is blocked by the player
if (MillArray[count2][1] == playpiece):
if (FutureMill[count2][2] == other and FutureMill[count2][3] == other):
score = score + 2
if (MillArray[count2][2] == playpiece):
if (FutureMill[count2][1] == other and FutureMill[count2][3] == other):
score = score + 2
if (MillArray[count2][3] == playpiece):
if (FutureMill[count2][1] == other and FutureMill[count2][2] == other):
score = score + 2
count2 = count2 + 1
counter2 = 1
while (counter2 < 4): #Finds if the piece played has any open connections
if (ConnectArray[piece][counter2] > 2):
score = score + 1
if (ConnectArray[piece][counter2] == other):
score = score - 1
if (ConnectArray[piece][counter2] == turn):
score = score + 1
counter2 = counter2 + 1
return score
#Function to compute score of future gameboard
def OpeningScoring(LegalPlacement, turn, other):
ScoreArray = [[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]]
counter = 0
Totalnum = RandOpenNum(LegalPlacement) + 1
while (counter < Totalnum): #cycles through all legal placements
score = 0
ScoreArray[0][counter] = LegalPlacement[counter]
count = 0
YES = False
while (YES == False): #Finds correct position of move in CheckArray
if (CheckArray[count] == LegalPlacement[counter]):
YES = True
piece = count
playpiece = LegalPlacement[counter]
else:
count = count+1
score = Scoring(piece, playpiece, score)
ScoreArray[1][counter] = score
ReverseFutureMove()
counter = counter + 1
return ScoreArray
def MovingScoring(Moves, counter1, turn, other):
ScoreArray2 = [[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]]
counter = 0
Totalnum = counter1 - 1
if (Totalnum == 0):
Totalnum = 1
while (counter < Totalnum): #cycles through all legal placements
score = 0
ScoreArray2[0][counter] = Moves[0][counter]
ScoreArray2[1][counter] = Moves[1][counter]
count = 0
YES = False
while (YES == False): #Finds correct position of move in CheckArray
if (OCheckArray[count] == Moves[0][counter]):
YES = True
removepiece = count
else:
count = count+1
ReverseOpening(removepiece, Futureboard, FutureMill)
count2 = 0
YES = False
while (YES == False): #Finds correct position of move in CheckArray
if (CheckArray[count2] == ScoreArray2[1][counter]):
YES = True
movespot = count2
playpiece = ScoreArray2[1][counter]
else:
count2 = count2+1
score = Scoring(movespot, playpiece, score)
ScoreArray2[2][counter] = score
ReverseFutureMove()
counter = counter + 1
return ScoreArray2
def Choosebestopenmove(ScoreArray):
counter = 0
counter2 = 0
counter3 = 0
counter4 = 0
best = 0
bestmove = 0
bestarray = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
check = 0
while (counter < 16): #Finds out what highest score is
if (ScoreArray[1][counter] > best):
best = ScoreArray[1][counter]
counter = counter + 1
while (counter3 < 16): #Collects move with that score
if (ScoreArray[1][counter3] == best):
bestarray[counter4] = ScoreArray[0][counter3]
counter4 = counter4 + 1
counter3 = counter3 + 1
check = RandOpenNum(bestarray)
if (check == 0): #Checks if there was more than one move with the highest score
while (counter2 < 16):
if (ScoreArray[1][counter2] == best):
bestmove = ScoreArray[0][counter2]
counter2 = counter2 + 1
else:
if (check > 0): #Randomly picks from set of best moves
pick = random.randint(0, check)
bestmove = bestarray[pick]
return bestmove
def Choosebestmove(ScoreArray):
counter = 0
counter2 = 0
counter3 = 0
counter4 = 0
count = 0
best = 0
bestmove = 0
bestarray = [[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]]
check = 0
while (counter < 16): #Finds out what highest score is
if (ScoreArray[2][counter] > best):
best = ScoreArray[2][counter]
counter = counter + 1
while (counter3 < 16): #Collects move with that score
if (ScoreArray[2][counter3] == best):
bestarray[0][counter4] = ScoreArray[0][counter3]
bestarray[1][counter4] = ScoreArray[1][counter3]
counter4 = counter4 + 1
if (counter4 == 15):
counter4 = 0
counter3 = counter3 + 1
while (count < 15):
if (bestarray[0][count] != 0 and bestarray[1][count] != 0):
check = check + 1
count = count + 1
if (check == 1): #Checks if there was more than one move with the highest score
while (counter2 < 16):
if (ScoreArray[2][counter2] == best):
bestmove = ScoreArray[0][counter2]
counter2 = counter2 + 1
else:
if (check > 1): #Randomly picks from set of best moves
pick = random.randint(0, check-1)
bestmove = bestarray[0][pick]
return bestmove #Returns the piece that is being moved, will access the place it moved to from the moves array
def ChooseSpot(turn): #function to determine which spot to choose
LegalPlacement = LegalChoices(turn) #Creates an array of legal choices
if (turn == 2):
ScoreArray = OpeningScoring(LegalPlacement, turn, other)
CHOOSE = Choosebestopenmove(ScoreArray)
YES = False
counter = 0
while (YES == False):
if (CheckArray[counter] == CHOOSE):
YES = True
CHANGE = ChangeOpening(counter, turn, CheckArray, MillArray) #updates arrays
FutureMill = MillArray
else:
counter = counter+1
if (turn == 1):
BigNum = RandOpenNum(LegalPlacement) #counts the elements in the legal choices array
CHOOSE = random.randint(0,BigNum) #will choose a random spot
YES = False
counter = 0
while (YES == False):
if (CheckArray[counter] == LegalPlacement[CHOOSE]):
YES = True
CHANGE = ChangeOpening(counter,turn, CheckArray, MillArray) #updates arrays
else:
counter = counter+1
return CHANGE #returns whether there is a new mill or not
def Removal(Choose,turn,other): # function to determine which piece to remove
if (Choose == 1):
LegalRemoval = LegalRemove(other) #creates an array of legal pieces to remove
BigNum = RandOpenNum(LegalRemoval) #counts the number of elements in legal remove array
CHOOSE = random.randint(0,BigNum) #chooses a random piece
YES = False
counter = 0
while (YES == False):
if (OCheckArray[counter] == LegalRemoval[CHOOSE]):
YES = True
CHANGE = ReverseOpening(counter, CheckArray, MillArray) #updates arrays after piece removed
else:
counter = counter+1
def resetgame():
ticker1 = 0
while (ticker1<8):
ticker2 = 1
while (ticker2<4):
MillArray[ticker1][ticker2] = OMillArray[ticker1][ticker2]
ticker2 = ticker2+1
ticker1 = ticker1+1
ticker3 = 0
while (ticker3 < 16):
CheckArray[ticker3] = OCheckArray[ticker3]
ticker3 = ticker3 + 1
def Moving(turn,other):
Moves = LegalMove(turn,other) #recieves the matrix of legal moves
ticker1 = 0
counter = 0
while (ticker1<15): #following determines how many elements in matrix
if (Moves[0][ticker1] != 0):
counter = counter+1
ticker1 = ticker1+1
else:
ticker1 = 15
if (counter == 0): # if no elements returns number to determine player has lost
return 50
else: #chooses a piece to move and where to
if (turn == 2):
ScoreArray2 = MovingScoring(Moves, counter, turn, other)
choose = Choosebestmove(ScoreArray2)
counter = 0
place = 0
YES = False
while (counter < 15):
if (Moves[0][counter] == choose):
place = counter
counter = counter + 1
ticker = 0
ticker2 = 0
while (ticker < 16):
if (OCheckArray[ticker] == choose):
ticker2 = ticker
ticker = ticker+1
Move = ReverseOpening(ticker2, CheckArray, MillArray) #updates arrays
ticker2 = 0
while (YES == False):
if (CheckArray[ticker2] == Moves[1][place]):
YES = True
else:
ticker2 = ticker2+1
CHANGE = ChangeOpening(ticker2, turn, CheckArray, MillArray) #updates arrays
if (turn == 1):
choose = random.randint(0,counter-1)
ticker = 0
YES = True
while (YES == True):
if (Moves[0][choose] == OCheckArray[ticker]):
YES = False
else:
ticker = ticker+1
Move = ReverseOpening(ticker, CheckArray, MillArray) #updates arrays
ticker = 0
while (YES == False):
if (Moves[1][choose] == CheckArray[ticker]):
YES = True
else:
ticker = ticker+1
CHANGE = ChangeOpening(ticker,turn, CheckArray, MillArray) #updates arrays
return CHANGE #returns whether mill made or not
def EndGameCheck(turn,other): #checks to see if less than 3 pieces for a player
LegalRemoval = LegalRemove(other)
BigNum = RandOpenNum(LegalRemoval)
if (BigNum < 2):
return 1
else:
return 0
###################################################################################
#main code for running the program
gamenum = 2000
while (gamenum > 0):
remaining = 10
turn = 1
other = 2
#opening stage while loop
while (remaining>0):
Choose = ChooseSpot(turn)
Remove = Removal(Choose,turn,other)
if (turn==1):
turn = 2
other = 1
elif (turn == 2):
turn = 1
other = 2
remaining = remaining - 1
#second stage while loop
GameEnd = False
while (GameEnd == False):
Move = Moving(turn,other)
Remove = Removal(Move,turn,other)
EndGame = EndGameCheck(turn,other)
if (EndGame == 1 or Move == 50):
GameEnd = True
if (Move == 50):
if (turn == 1):
p2win = p2win + 1
else:
p1win = p1win + 1
if (EndGame == 1):
if (turn == 1):
p1win = p1win + 1
else:
p2win = p2win + 1
if (turn==1):
turn = 2
other = 1
elif (turn == 2):
turn = 1
other = 2
resetgame()
gamenum = gamenum - 1
print p1win
print p2win
main()