Commit 6dba7d8f authored by Blažek, Matěj's avatar Blažek, Matěj 💬
Browse files

pridan KnuthBot

parent f4e9d817
import mastermind
import itertools
from random import *
import sys
from timeit import default_timer as timer
class KnuthBot:
def __init__(self,codelength,numberOfColors):
self.codelength = codelength
self.turnsPlayed = list()
self.rewards = list()
self.numberOfColors = numberOfColors
self.colors = list(range(numberOfColors))
self.possibleCodes = list(itertools.product(self.colors,repeat = self.codelength))
self.unplayedMoves = self.possibleCodes.copy()
self.available_rewards = list(itertools.product(list(x for x in range(self.codelength+1)), repeat=2))
def resetBot(self):
self.turnsPlayed.clear()
self.rewards.clear()
self.possibleCodes = list(itertools.product(self.colors,repeat = self.codelength))
self.unplayedMoves = self.possibleCodes.copy()
def giveRewards(self,rewards):
self.rewards.append(rewards)
def getName(self):
return "KnuthBot"
def playMove(self):
if len(self.turnsPlayed) == 0:
ret =[0,0]
for x in range(self.codelength - len(ret)):
ret.append(1)
self.turnsPlayed.append(ret)
return ret
else:
last_move = self.turnsPlayed[-1]
white_pins = self.rewards[-1][0]
red_pins = self.rewards[-1][1]
new_moves = list()
for move in self.possibleCodes:
if (self.compare_to_played(last_move,move,red_pins,white_pins)):
new_moves.append(move)
#print(move)
#print(len(self.possibleCodes))
self.possibleCodes = new_moves.copy()
#print(len(self.possibleCodes))
move = self.get_best_move()
self.turnsPlayed.append(move)
self.unplayedMoves.remove(move)
#print(move)
return move
def get_best_move(self):
removed = list()
for index,code in enumerate(self.unplayedMoves):
#print("trying",index,"code")
score = [0 for x in range(len(self.available_rewards))]
for index,pins in enumerate(self.available_rewards):
white_pins,red_pins = pins
for compared in self.possibleCodes:
if not self.compare_to_played(code,compared,red_pins,white_pins):
score[index] +=1
#print(score)
removed.append(min(score))
correct_answer= self.find_correct_answer(removed)
return correct_answer
def find_correct_answer(self,scores):
max = 0
correct_answers = list()
for index,score in enumerate(scores):
if score == max:
correct_answers.append(index)
if score > max:
max = score
correct_answers.clear()
correct_answers.append(index)
for answer in correct_answers:
if self.unplayedMoves[answer] in self.possibleCodes:
return self.unplayedMoves[answer]
return self.unplayedMoves[correct_answers[0]]
def compare_to_played(self,played,compared,red_pins,white_pins):
deepcpy = list(played).copy()
compared = list(compared)
red_guesses = 0
white_guesses = 0
for ind,color in enumerate(compared):
if color == played[ind]:
red_guesses +=1
deepcpy[ind] = -1
compared[ind] = -2
for ind,color in enumerate(compared):
if color in deepcpy:
white_guesses +=1
deepcpy.remove(color)
return white_guesses == white_pins and red_guesses == red_pins
if __name__ == "__main__":
gamesToPlay = 100
colors = 6
size = 4
if (len(sys.argv) == 4):
gamesToPlay = argv[1]
colors = argv[2]
size = argv[3]
mm = mastermind.Mastermind(colors,size)
codelen = mm.getCodelength()
clrs = mm.getNumberOfColors()
bot = KnuthBot(codelen,clrs)
cost = 0
playedGames = 0
start = timer()
# ...
while playedGames < gamesToPlay:
start = timer()
for x in range(10):
guesses = bot.playMove()
white_pins,red_pins = mm.play_turn(guesses)
#print(white_pins,red_pins)
bot.giveRewards([white_pins,red_pins])
if red_pins == size:
bot.resetBot()
break
cost += (x+1)
playedGames +=1
end = timer()
print("One game took",end - start)
if playedGames % 1 == 0:
print("Simulated",playedGames,"games")
averageCost = cost / playedGames
print("Average cost per game is:",averageCost)
\ No newline at end of file
import mastermind
import itertools
from random import *
import sys
from timeit import default_timer as timer
class KnuthHitBot:
def __init__(self,codelength,numberOfColors):
self.codelength = codelength
self.turnsPlayed = list()
self.rewards = list()
self.numberOfColors = numberOfColors
self.colors = list(range(numberOfColors))
self.possibleCodes = list(itertools.product(self.colors,repeat = self.codelength))
self.unplayedMoves = self.possibleCodes.copy()
self.available_rewards = list(itertools.product(list(x for x in range(self.codelength+1)), repeat=2))
def resetBot(self):
self.turnsPlayed.clear()
self.rewards.clear()
self.possibleCodes = list(itertools.product(self.colors,repeat = self.codelength))
self.unplayedMoves = self.possibleCodes.copy()
def giveRewards(self,rewards):
self.rewards.append(rewards)
def getName(self):
return "KnuthHitBot"
def playMove(self):
if len(self.turnsPlayed) == 0:
ret =[0,0]
for x in range(self.codelength - len(ret)):
ret.append(1)
self.turnsPlayed.append(ret)
return ret
else:
last_move = self.turnsPlayed[-1]
white_pins = self.rewards[-1][0]
red_pins = self.rewards[-1][1]
new_moves = list()
for move in self.possibleCodes:
if (self.compare_to_played(last_move,move,red_pins,white_pins)):
new_moves.append(move)
#print(move)
#print(len(self.possibleCodes))
self.possibleCodes = new_moves.copy()
#print(len(self.possibleCodes))
move = self.get_best_move()
self.turnsPlayed.append(move)
self.unplayedMoves.remove(move)
print(move)
return move
def get_best_move(self):
score = list()
for index,code in enumerate(self.unplayedMoves):
#print("trying",index,"code")
hit = [0 for x in range(len(self.available_rewards))]
for index,pins in enumerate(self.available_rewards):
white_pins,red_pins = pins
for compared in self.possibleCodes:
if not self.compare_to_played(code,compared,red_pins,white_pins):
hit[index] +=1
#print(score)
score.append(len(self.possibleCodes) - max(hit))
correct_answer= self.find_correct_answer(score)
return correct_answer
def find_correct_answer(self,scores):
max = 0
correct_answers = list()
for index,score in enumerate(scores):
if score == max:
correct_answers.append(index)
if score > max:
max = score
correct_answers.clear()
correct_answers.append(index)
for answer in correct_answers:
if self.unplayedMoves[answer] in self.possibleCodes:
return self.unplayedMoves[answer]
return self.unplayedMoves[correct_answers[0]]
def compare_to_played(self,played,compared,red_pins,white_pins):
deepcpy = list(played).copy()
compared = list(compared)
red_guesses = 0
white_guesses = 0
for ind,color in enumerate(compared):
if color == played[ind]:
red_guesses +=1
deepcpy[ind] = -1
compared[ind] = -2
for ind,color in enumerate(compared):
if color in deepcpy:
white_guesses +=1
deepcpy.remove(color)
return white_guesses == white_pins and red_guesses == red_pins
if __name__ == "__main__":
gamesToPlay = 10
colors = 6
size = 4
if (len(sys.argv) == 4):
gamesToPlay = argv[1]
colors = argv[2]
size = argv[3]
mm = mastermind.Mastermind(colors,size)
codelen = mm.getCodelength()
clrs = mm.getNumberOfColors()
bot = KnuthHitBot(codelen,clrs)
cost = 0
playedGames = 0
start = timer()
# ...
while playedGames < gamesToPlay:
start = timer()
for x in range(10):
guesses = bot.playMove()
white_pins,red_pins = mm.play_turn(guesses)
#print(white_pins,red_pins)
bot.giveRewards([white_pins,red_pins])
if red_pins == size:
bot.resetBot()
break
cost += (x+1)
playedGames +=1
end = timer()
print("One game took",end - start)
if playedGames % 1 == 0:
print("Simulated",playedGames,"games")
averageCost = cost / playedGames
print("Average cost per game is:",averageCost)
\ No newline at end of file
......@@ -5,6 +5,7 @@ import sys
import RandoBot
import WikiRandomChoiceBot
import WikiChoosingBot
import KnuthBot
if __name__ == "__main__":
gamesToPlay = 10000
......@@ -20,6 +21,7 @@ if __name__ == "__main__":
bots.append(RandoBot.RandoBot(size,colors))
bots.append(WikiRandomChoiceBot.WikiRandomChoiceBot(size,colors))
bots.append(WikiChoosingBot.WikiChoosingBot(size,colors))
bots.append(KnuthBot.KnuthBot(size,colors))
for bot in bots:
cost = 0
playedGames = 0
......@@ -33,7 +35,7 @@ if __name__ == "__main__":
bot.resetBot()
cost += (x+1)
playedGames +=1
if playedGames % 100 == 0:
if playedGames % 1 == 0:
print("Simulated",playedGames,"games of", bot.getName())
averageCost = cost / playedGames
print("Average cost per game of",bot.getName(), "is:",averageCost,"after",playedGames,"games")
......
run any file without commands to play predifined number of games or execute program with arguments: program_name games_to_play colors size
\ No newline at end of file
Average cost per game of RandoBot is: 9.98847 after 100000 games
Average cost per game of WikiRandomChoiceBot is: 5.50339 after 100000 games
Average cost per game of WikiChoosingBot is: 5.48051 after 100000 games
Average cost per game of RandoBot is: 9.9764 after 2500 games
Average cost per game of WikiRandomChoiceBot is: 4.6456 after 2500 games
Average cost per game of WikiChoosingBot is: 4.6252 after 2500 games
Average cost per game of KnuthBot is: 4.4752 after 2500 games
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment