Add files via upload

Fixed a bug with playing cards that involve discarding.  Previously gain-trash cards would discard the gained card rather than the played under some conditions.
Fixed a bug with scoring the game that cause the game crash.
Added a Big Money Bot.
This commit is contained in:
Brad Stein 2018-01-04 01:50:34 -06:00 committed by GitHub
parent c24103b969
commit 206d016ad3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 91 additions and 30 deletions

View File

@ -44,6 +44,9 @@ class Card:
def get_type(self): def get_type(self):
return self.__type return self.__type
def get_points(self):
return self.__value
def get_cost(self): def get_cost(self):
return self.__cost return self.__cost

29
game.py
View File

@ -1,5 +1,6 @@
from table.table import Table from table.table import Table
from player.player import Player from player.player import Player
from player.bot import Bot
from card.card import Card from card.card import Card
from card.militia import Militia from card.militia import Militia
from card.moat import Moat from card.moat import Moat
@ -25,7 +26,7 @@ def play_game(game_table):
def setup_new_game(game_list, parameter, card_info): def setup_new_game(game_list, parameter, card_info):
t = Table() t = Table()
humans = parameter[0] humans = parameter[0]
# bots = parameter[1] bots = parameter[1]
index = 0 index = 0
for p in parameter[2:]: for p in parameter[2:]:
@ -35,7 +36,7 @@ def setup_new_game(game_list, parameter, card_info):
card_info[index][3], card_info[index][4], card_info[index][5], card_info[index][3], card_info[index][4], card_info[index][5],
card_info[index][6], card_info[index][7], None) card_info[index][6], card_info[index][7], None)
if i == 0: if i == 0:
t.add_pile(card) t.create_pile(card)
else: else:
t.get_pile(t.get_pile_index_of_card(card_info[index][0])).add_card(card) t.get_pile(t.get_pile_index_of_card(card_info[index][0])).add_card(card)
index += 1 index += 1
@ -46,18 +47,18 @@ def setup_new_game(game_list, parameter, card_info):
human.draw_hand() human.draw_hand()
t.add_player(human) t.add_player(human)
# for i in range(bots): for i in range(bots):
# bot = Player(False, t) bot = Bot(False, t)
# bot.draw_deck(t, get_starting_deck()) bot.draw_deck(t, get_starting_deck())
# bot.draw_hand() bot.draw_hand()
# t.add_player(bot) t.add_player(bot)
game_list.append(t) game_list.append(t)
def get_game_parameters(): def get_game_parameters():
# humans, bots, card #1, card #2, ... etc # humans, bots, card #1, card #2, ... etc
return [2, 1, True, True, True, True, True, True, False, True, True, True, True, True, True, True, True, True, True] return [1, 1, True, True, True, True, True, True, False, True, True, True, True, True, True, True, True, True, True]
def get_card_info(): def get_card_info():
@ -66,10 +67,10 @@ def get_card_info():
return [["Copper", 0, Card.CardType.Treasure, 0, 1, 0, 0, 0, Card, 60], # 1 return [["Copper", 0, Card.CardType.Treasure, 0, 1, 0, 0, 0, Card, 60], # 1
["Silver", 3, Card.CardType.Treasure, 0, 2, 0, 0, 0, Card, 40], # 2 ["Silver", 3, Card.CardType.Treasure, 0, 2, 0, 0, 0, Card, 40], # 2
["Gold", 6, Card.CardType.Treasure, 0, 3, 0, 0, 0, Card, 30], # 3 ["Gold", 6, Card.CardType.Treasure, 0, 3, 0, 0, 0, Card, 30], # 3
["Estate", 2, Card.CardType.Victory, 1, 0, 0, 0, 0, Card, 24], # 4 ["Estate", 2, Card.CardType.Victory, 1, 0, 0, 0, 0, Card, 40], # 4
["Dutchy", 5, Card.CardType.Victory, 3, 0, 0, 0, 0, Card, 12], # 5 ["Dutchy", 5, Card.CardType.Victory, 3, 0, 0, 0, 0, Card, 12], # 5
["Province", 8, Card.CardType.Victory, 6, 0, 0, 0, 0, Card, 12], # 6 ["Province", 8, Card.CardType.Victory, 6, 0, 0, 0, 0, Card, 12], # 6
["Curse", 0, Card.CardType.Curse, -1, 0, 0, 0, 0, Card, 30], # 7 ["Curse", 0, Card.CardType.Curse, -1, 0, 0, 0, 0, Card, 10], # 7
["Cellar", 2, Card.CardType.Action, 0, 0, 1, 0, 0, Cellar, 10], # 8 ["Cellar", 2, Card.CardType.Action, 0, 0, 1, 0, 0, Cellar, 10], # 8
["Market", 5, Card.CardType.Action, 0, 1, 1, 1, 1, Card, 10], # 9 ["Market", 5, Card.CardType.Action, 0, 1, 1, 1, 1, Card, 10], # 9
["Merchant", 3, Card.CardType.Action, 0, 0, 1, 0, 1, Merchant, 10], # 10 ["Merchant", 3, Card.CardType.Action, 0, 0, 1, 0, 1, Merchant, 10], # 10
@ -106,14 +107,14 @@ def get_card_info():
def get_starting_deck(): def get_starting_deck():
# return [["Copper", 7], ["Estate", 3]] return [["Copper", 7], ["Estate", 3]]
# return [["Market", 2], ["Merchant", 2], ["Smithy", 2], ["Village", 2], ["Moat", 2]] # return [["Market", 2], ["Merchant", 2], ["Smithy", 2], ["Village", 2], ["Moat", 2]]
# return [["Militia", 4], ["Cellar", 3], ["Moat", 3]] # return [["Militia", 4], ["Cellar", 3], ["Moat", 3]]
# return [["Silver", 7], ["Merchant", 3]] # return [["Silver", 7], ["Merchant", 3]]
# return [["Copper", 4], ["Mine", 2], ["Remodel", 2], ["Workshop", 2]] # return [["Copper", 4], ["Mine", 2], ["Remodel", 2], ["Workshop", 2]]
return [["Copper", 1], ["Silver", 1], ["Gold", 1], ["Estate", 1], ["Dutchy", 1], ["Province", 1], ["Cellar", 1], # return [["Copper", 1], ["Silver", 1], ["Gold", 1], ["Estate", 1], ["Dutchy", 1], ["Province", 1], ["Cellar", 1],
["Market", 1], ["Merchant", 1], ["Militia", 1], ["Mine", 1], ["Moat", 1], ["Remodel", 1], ["Smithy", 1], # ["Market", 1], ["Merchant", 1], ["Militia", 1], ["Mine", 1], ["Moat", 1], ["Remodel", 1], ["Smithy", 1],
["Village", 1], ["Workshop", 1]] # ["Village", 1], ["Workshop", 1]]
main() main()

34
player/bot.py Normal file
View File

@ -0,0 +1,34 @@
from player.player import Player
from card.card import Card
class Bot(Player):
def take_action(self):
print("\nAs a BIG MONEY BOT, I'm skipping this unnecessary action phase. Beep-boop, bow to me humans!")
#This method will only be called for this bot when it is time to play treasures, it will play all of them always.
def get_play_input(self, message):
choice = -1
hand = self.get_hand().get_supply()
for c in hand:
if c.get_type() == Card.CardType.Treasure:
choice = hand.index(c)
print(message + str(choice))
return choice
#This method will only be called when it is time to buy things, a very simple logic will decide its action.
def get_buy_input(self, message):
coin = self._Player__purchase_power
choice = -1
if coin >= 8:
choice = self.get_table().get_pile_index_of_card("Province")
elif coin >= 6:
choice = self.get_table().get_pile_index_of_card("Gold")
elif coin >= 3:
choice = self.get_table().get_pile_index_of_card("Silver")
print(message + str(choice))
return choice

View File

@ -42,7 +42,18 @@ class Player:
return self.__table.get_players().index(self) return self.__table.get_players().index(self)
def get_score(self): def get_score(self):
return 0 score = 0
for c in self.__deck.get_supply():
score += c.get_points()
for c in self.__hand.get_supply():
score += c.get_points()
for c in self.__discard.get_supply():
score += c.get_points()
return score
def draw_card(self): def draw_card(self):
self.__deck.transfer_top_card(self.__hand) self.__deck.transfer_top_card(self.__hand)
@ -90,7 +101,7 @@ class Player:
def play_card(self, acceptable_card_type, chances, counter): def play_card(self, acceptable_card_type, chances, counter):
if chances > 0 and self.__hand.contains_one_of(acceptable_card_type): if chances > 0 and self.__hand.contains_one_of(acceptable_card_type):
hand_index = self.__get_play_input("\nPlease identify a card from hand to play by providing its index: ") hand_index = self.get_play_input("\nPlease identify a card from hand to play by providing its index: ")
self.__check_play_card(hand_index, counter, acceptable_card_type, chances) self.__check_play_card(hand_index, counter, acceptable_card_type, chances)
elif chances <= 0: elif chances <= 0:
print("You have used up all of your chances to enter a valid integer; forfeiting remaining plays.") print("You have used up all of your chances to enter a valid integer; forfeiting remaining plays.")
@ -119,7 +130,7 @@ class Player:
def buy_card(self, chances): def buy_card(self, chances):
self.__table.print() self.__table.print()
while self.__buys > 0 and not self.__table.are_there_any_empty_piles() and chances > 0: while self.__buys > 0 and not self.__table.are_there_any_empty_piles() and chances > 0:
pile_index = self.__get_buy_input("\nPlease identify a pile from the table that you'd like to purchase: ") pile_index = self.get_buy_input("\nPlease identify a pile from the table that you'd like to purchase: ")
if pile_index < 0: if pile_index < 0:
print("You have elected to forfeit any remaining plays.") print("You have elected to forfeit any remaining plays.")
@ -163,8 +174,9 @@ class Player:
self.play_card(acceptable_card_type, chances - 1, counter) self.play_card(acceptable_card_type, chances - 1, counter)
elif self.__hand.get_card(hand_index).get_type() in acceptable_card_type: elif self.__hand.get_card(hand_index).get_type() in acceptable_card_type:
print("Player " + str(self.get_player_index()) + " playing: " + self.__hand.get_card(hand_index).get_name()) print("Player " + str(self.get_player_index()) + " playing: " + self.__hand.get_card(hand_index).get_name())
self.__hand.get_card(hand_index).play() play_card = self.__hand.get_card(hand_index)
self.__hand.transfer_card_by_card(self.__hand.get_card(hand_index), self.__discard) play_card.play()
self.__hand.transfer_card_by_card(play_card, self.__discard)
if counter is not None: if counter is not None:
counter.int -= 1 counter.int -= 1
self.__print() self.__print()
@ -173,10 +185,10 @@ class Player:
self.play_card(acceptable_card_type, chances - 1, counter) self.play_card(acceptable_card_type, chances - 1, counter)
# The following two methods are identical under different names so they can be overridden by bot classes later # The following two methods are identical under different names so they can be overridden by bot classes later
def __get_play_input(self, message): def get_play_input(self, message):
return int(input(message)) return int(input(message))
def __get_buy_input(self, message): def get_buy_input(self, message):
return int(input(message)) return int(input(message))
def __print_discard(self): def __print_discard(self):
@ -202,4 +214,10 @@ class Player:
self.__purchase_power = 0 self.__purchase_power = 0
def __str__(self): def __str__(self):
return "Player " + self.get_player_index() + "." result = "Player " + str(self.get_player_index())
if self.__is_human:
result += " (human)"
else:
result += " (bot)"
return result

View File

@ -1,5 +1,9 @@
from table.supply import Supply from table.supply import Supply
class Pile(Supply): class Pile(Supply):
def __init__(self, card):
self.__card_group = card
Supply.__init__(self)
def get_card_group(self): def get_card_group(self):
return self._Supply__card[0] return self.__card_group

View File

@ -22,8 +22,8 @@ class Table:
def get_trash(self): def get_trash(self):
return self.__trash return self.__trash
def add_pile(self, card): def create_pile(self, card):
p = Pile() p = Pile(card)
p.add_card(card) p.add_card(card)
card.setup() card.setup()
self.__pile.append(p) self.__pile.append(p)
@ -54,17 +54,18 @@ class Table:
def play(self): def play(self):
turn = 0 turn = 0
# turn < 10 is for testing, otherwise endless as buying card is not yet done # turn < 10 is for testing, otherwise endless as buying card is not yet done
while not self.are_there_any_empty_piles() and turn < 10: while not self.are_there_any_empty_piles(): # and turn < 10:
self.print() self.print()
self.__player[turn % len(self.__player)].take_turn() self.__player[turn % len(self.__player)].take_turn()
turn += 1 turn += 1
else: else:
self.print() self.print()
for p in self.__player: for p in self.__player:
print("" + str(p) + " scored " + str(p.get_score()) + " points.")
if p.get_score() > self.__winning_score: if p.get_score() > self.__winning_score:
self.__winning_score = p.get_score self.__winning_score = p.get_score()
self.__winner = p self.__winner = p
print("\n\nPlayer " + str(self.__winner) + " won with " + str(self.__winning_score) + " points.\n\n") print("\n\n" + str(self.__winner) + " won with " + str(self.__winning_score) + " points.\n\n")
def print(self): def print(self):
print("\nPiles: ") print("\nPiles: ")

View File

@ -1,5 +1,5 @@
from table.pile import Pile from table.supply import Supply
class Trash(Pile): class Trash(Supply):
pass pass