mirror of
https://github.com/neogeek23/Dominion-Strategy-Simulator.git
synced 2026-02-04 11:08:18 +00:00
Add files via upload
first upload under new name
This commit is contained in:
parent
4b937f9db3
commit
ce4eddcf72
42
card.py
Normal file
42
card.py
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
from enum import Enum, auto
|
||||||
|
|
||||||
|
|
||||||
|
class Card:
|
||||||
|
class CardType(Enum):
|
||||||
|
Action = auto()
|
||||||
|
Attack = auto()
|
||||||
|
Treasure = auto()
|
||||||
|
Victory = auto()
|
||||||
|
Curse = auto()
|
||||||
|
Reaction = auto()
|
||||||
|
|
||||||
|
def __init__(self, name, cost, cardtype, value, coin, action, reaction, buy, draw, effect):
|
||||||
|
self.__name = name
|
||||||
|
self.__cost = cost
|
||||||
|
self.__coin = coin
|
||||||
|
self.__type = cardtype
|
||||||
|
self.__action = action
|
||||||
|
self.__buy = buy
|
||||||
|
self.__draw = draw
|
||||||
|
self.__effect = effect
|
||||||
|
self.__value = value
|
||||||
|
self.__reaction = reaction
|
||||||
|
|
||||||
|
def play(self, player):
|
||||||
|
player.add_actions(self.__action)
|
||||||
|
player.add_buys(self.__buy)
|
||||||
|
player.add_purchase_power(self.__coin)
|
||||||
|
player.add_reactions(self.__reaction)
|
||||||
|
self.effect()
|
||||||
|
|
||||||
|
def effect(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def get_name(self):
|
||||||
|
return self.__name
|
||||||
|
|
||||||
|
def get_type(self):
|
||||||
|
return self.__type
|
||||||
|
|
||||||
|
def identify(self):
|
||||||
|
return self.__name + ", " + str(self.__type) + ", " + str(self.__cost)
|
||||||
3
counter.py
Normal file
3
counter.py
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
class Counter:
|
||||||
|
def __init__(self, n):
|
||||||
|
self.int = n
|
||||||
7
deck.py
Normal file
7
deck.py
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
from supply import Supply
|
||||||
|
from random import shuffle
|
||||||
|
|
||||||
|
|
||||||
|
class Deck(Supply):
|
||||||
|
def shuffle(self):
|
||||||
|
shuffle(self._Supply__card)
|
||||||
8
discard.py
Normal file
8
discard.py
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
from supply import Supply
|
||||||
|
|
||||||
|
|
||||||
|
class Discard(Supply):
|
||||||
|
def cycle_card(self, deck):
|
||||||
|
while self.get_remaining() > 0:
|
||||||
|
self.transfer_top_card(deck)
|
||||||
|
deck.shuffle()
|
||||||
74
game.py
Normal file
74
game.py
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
from table import Table
|
||||||
|
from player import Player
|
||||||
|
from card import Card
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
game = list()
|
||||||
|
card_info = get_card_info()
|
||||||
|
setup_new_game(game, get_game_parameters(), card_info)
|
||||||
|
play_game(game[0])
|
||||||
|
|
||||||
|
|
||||||
|
def setup_new_game(game_list, parameter, card_info):
|
||||||
|
t = Table()
|
||||||
|
humans = parameter[0]
|
||||||
|
bots = parameter[1]
|
||||||
|
|
||||||
|
index = 0
|
||||||
|
for p in parameter[2:]:
|
||||||
|
if p:
|
||||||
|
card = Card(card_info[index][0], card_info[index][1], card_info[index][2], card_info[index][3],
|
||||||
|
card_info[index][4], card_info[index][5], card_info[index][6], card_info[index][7],
|
||||||
|
card_info[index][8], card_info[index][9])
|
||||||
|
t.add_pile(card, card_info[index][10])
|
||||||
|
index += 1
|
||||||
|
|
||||||
|
for i in range(humans):
|
||||||
|
human = Player(True, t)
|
||||||
|
human.draw_deck(t, get_starting_deck())
|
||||||
|
human.draw_hand()
|
||||||
|
t.add_player(human)
|
||||||
|
|
||||||
|
for i in range(bots):
|
||||||
|
bot = Player(False, t)
|
||||||
|
bot.draw_deck(t, get_starting_deck())
|
||||||
|
bot.draw_hand()
|
||||||
|
t.add_player(bot)
|
||||||
|
|
||||||
|
game_list.append(t)
|
||||||
|
|
||||||
|
|
||||||
|
def play_game(game_table):
|
||||||
|
game_table.play()
|
||||||
|
|
||||||
|
|
||||||
|
def get_game_parameters():
|
||||||
|
return [1, 1, True, True, True, True, True, True, False, True, True, True, True, True, True, True, True, True, True]
|
||||||
|
|
||||||
|
|
||||||
|
def get_card_info():
|
||||||
|
# [name, cost, cardtype, v, c, a, r, b, d, effect, count] - value to pass to Card()
|
||||||
|
return [["Copper", 0, Card.CardType.Treasure, 0, 1, 0, 0, 0, 0, None, 60],
|
||||||
|
["Silver", 3, Card.CardType.Treasure, 0, 2, 0, 0, 0, 0, None, 40],
|
||||||
|
["Gold", 6, Card.CardType.Treasure, 0, 3, 0, 0, 0, 0, None, 30],
|
||||||
|
["Estate", 2, Card.CardType.Victory, 1, 0, 0, 0, 0, 0, None, 24],
|
||||||
|
["Dutchy", 5, Card.CardType.Victory, 3, 0, 0, 0, 0, 0, None, 12],
|
||||||
|
["Province", 8, Card.CardType.Victory, 6, 0, 0, 0, 0, 0, None, 12],
|
||||||
|
["Curse", 0, Card.CardType.Curse, -1, 0, 0, 0, 0, 0, None, 30],
|
||||||
|
["Cellar", 2, Card.CardType.Action, 0, 0, 1, 0, 0, 0, "Name", 10],
|
||||||
|
["Market", 5, Card.CardType.Action, 0, 1, 1, 0, 1, 1, None, 10],
|
||||||
|
["Merchant", 3, Card.CardType.Action, 0, 0, 1, 0, 0, 1, "Name", 10],
|
||||||
|
["Militia", 4, Card.CardType.Attack, 0, 2, 0, 1, 0, 0, "Name", 10],
|
||||||
|
["Mine", 5, Card.CardType.Action, 0, 0, 0, 0, 0, 0, "Name", 10],
|
||||||
|
["Moat", 2, Card.CardType.Reaction, 0, 0, 0, 0, 0, 2, "Name", 10],
|
||||||
|
["Remodel", 4, Card.CardType.Action, 0, 0, 0, 0, 0, 0, "Name", 10],
|
||||||
|
["Smithy", 4, Card.CardType.Action, 0, 0, 0, 0, 0, 3, None, 10],
|
||||||
|
["Village", 3, Card.CardType.Action, 0, 0, 2, 0, 0, 1, None, 10],
|
||||||
|
["Workshop", 4, Card.CardType.Action, 0, 0, 0, 0, 0, 0, "Name", 10]]
|
||||||
|
|
||||||
|
|
||||||
|
def get_starting_deck():
|
||||||
|
return [["Copper", 7], ["Estate", 3]]
|
||||||
|
|
||||||
|
main()
|
||||||
28
hand.py
Normal file
28
hand.py
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
from supply import Supply
|
||||||
|
|
||||||
|
|
||||||
|
class Hand(Supply):
|
||||||
|
def contains_one_of(self, acceptible_types):
|
||||||
|
result = False
|
||||||
|
unique_types = self.__get_unique_types()
|
||||||
|
|
||||||
|
for at in acceptible_types:
|
||||||
|
result |= at in unique_types
|
||||||
|
return result
|
||||||
|
|
||||||
|
def __get_unique_types(self):
|
||||||
|
unique_type = list()
|
||||||
|
|
||||||
|
for c in self._Supply__card:
|
||||||
|
current_type = c.get_type()
|
||||||
|
if not current_type in unique_type:
|
||||||
|
unique_type.append(current_type)
|
||||||
|
return unique_type
|
||||||
|
|
||||||
|
def get_card_type_count(self, card_type):
|
||||||
|
result = 0
|
||||||
|
|
||||||
|
for c in self._Supply__card:
|
||||||
|
if c.get_type() == card_type:
|
||||||
|
result += 1
|
||||||
|
return result
|
||||||
5
pile.py
Normal file
5
pile.py
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
from supply import Supply
|
||||||
|
|
||||||
|
class Pile(Supply):
|
||||||
|
def get_card_group(self):
|
||||||
|
return self._Supply__card[0]
|
||||||
145
player.py
Normal file
145
player.py
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
from deck import Deck
|
||||||
|
from discard import Discard
|
||||||
|
from hand import Hand
|
||||||
|
from card import Card
|
||||||
|
from counter import Counter
|
||||||
|
|
||||||
|
|
||||||
|
class Player:
|
||||||
|
def __init__(self, human, table):
|
||||||
|
self.__deck = Deck()
|
||||||
|
self.__discard = Discard()
|
||||||
|
self.__hand = Hand()
|
||||||
|
self.__purchase_power = 0
|
||||||
|
self.__actions = Counter(0)
|
||||||
|
self.__buys = 0
|
||||||
|
self.__draws = 0
|
||||||
|
self.__reactions = Counter(0)
|
||||||
|
self.__is_human = human
|
||||||
|
self.__table = table
|
||||||
|
|
||||||
|
def add_actions(self, n):
|
||||||
|
self.__actions.int += n
|
||||||
|
|
||||||
|
def add_purchase_power(self, n):
|
||||||
|
self.__purchase_power += n
|
||||||
|
|
||||||
|
def add_buys(self, n):
|
||||||
|
self.__buys += n
|
||||||
|
|
||||||
|
def add_draws(self, n):
|
||||||
|
self.__draws += n
|
||||||
|
|
||||||
|
def add_reactions(self, n):
|
||||||
|
self.__reactions.int += n
|
||||||
|
|
||||||
|
def get_score(self):
|
||||||
|
return 0
|
||||||
|
|
||||||
|
def draw_card(self):
|
||||||
|
self.__deck.transfer_top_card(self.__hand)
|
||||||
|
|
||||||
|
def draw_cards(self, how_many):
|
||||||
|
spillover = how_many - self.__deck.get_remaining()
|
||||||
|
|
||||||
|
if spillover > 0:
|
||||||
|
for i in range(how_many - spillover):
|
||||||
|
self.draw_card()
|
||||||
|
|
||||||
|
self.__discard.cycle_card(self.__deck)
|
||||||
|
|
||||||
|
for i in range(spillover):
|
||||||
|
self.draw_card()
|
||||||
|
else:
|
||||||
|
for i in range(how_many):
|
||||||
|
self.draw_card()
|
||||||
|
|
||||||
|
def draw_deck(self, table, deck_setup):
|
||||||
|
for ds in deck_setup:
|
||||||
|
index = table.get_pile_index_of_card(ds[0])
|
||||||
|
for i in range(ds[1]):
|
||||||
|
table.get_pile(index).transfer_top_card(self.__deck)
|
||||||
|
self.__deck.shuffle()
|
||||||
|
|
||||||
|
def draw_hand(self):
|
||||||
|
self.draw_cards(5)
|
||||||
|
|
||||||
|
def discard_remaining_hand(self):
|
||||||
|
while self.__hand.get_remaining() > 0:
|
||||||
|
self.__hand.transfer_top_card(self.__discard)
|
||||||
|
|
||||||
|
def __print_hand(self):
|
||||||
|
print("Hand:")
|
||||||
|
self.__hand.print()
|
||||||
|
|
||||||
|
def __print_discard(self):
|
||||||
|
print("Discard:")
|
||||||
|
self.__discard.print()
|
||||||
|
|
||||||
|
def __print_deck(self):
|
||||||
|
print("Deck")
|
||||||
|
self.__deck.print()
|
||||||
|
|
||||||
|
def __gain_turn_events(self):
|
||||||
|
self.add_actions(1)
|
||||||
|
self.add_buys(1)
|
||||||
|
|
||||||
|
def play_card(self, acceptable_card_type, chances, counter):
|
||||||
|
if chances > 0 and self.__hand.contains_one_of(acceptable_card_type):
|
||||||
|
hand_index = int(input("Please identify a card from hand you would like to play by providing its index: "))
|
||||||
|
|
||||||
|
if self.__hand.get_card(hand_index).get_type() in acceptable_card_type:
|
||||||
|
self.__hand.get_card(hand_index).play(self)
|
||||||
|
self.__hand.transfer_card(hand_index, self.__discard)
|
||||||
|
if counter is not None:
|
||||||
|
counter.int -= 1
|
||||||
|
elif hand_index < 0:
|
||||||
|
print("You have elected to forfeit any remaining plays.")
|
||||||
|
if counter is not None:
|
||||||
|
counter.int = 0
|
||||||
|
else:
|
||||||
|
self.play_card(acceptable_card_type, chances - 1, counter)
|
||||||
|
elif chances <= 0:
|
||||||
|
print("You have used up all of your chances to enter a positive integer; forfeiting remaining plays.")
|
||||||
|
else:
|
||||||
|
print("There are no more acceptable cards in hand, moving to next phase.")
|
||||||
|
if counter is not None:
|
||||||
|
counter.int = 0
|
||||||
|
|
||||||
|
def take_action(self):
|
||||||
|
print("Please play an Action, Attack, or Reaction card until you have no remaining actions.")
|
||||||
|
while self.__actions.int > 0:
|
||||||
|
self.play_card([Card.CardType.Action, Card.CardType.Attack, Card.CardType.Reaction], 3, self.__actions)
|
||||||
|
|
||||||
|
def give_reaction(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def take_reaction(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def take_buy(self):
|
||||||
|
print("Please play all Treasure cards that you want to play.")
|
||||||
|
|
||||||
|
play_another = Counter(self.__hand.get_card_type_count(Card.CardType.Treasure))
|
||||||
|
while play_another.int > 0:
|
||||||
|
self.play_card([Card.CardType.Treasure], 3, play_another)
|
||||||
|
self.buy_card()
|
||||||
|
|
||||||
|
def buy_card(self):
|
||||||
|
while self.__buys > 0 and not self.__table.are_there_any_empty_piles():
|
||||||
|
pile_index = int(input("Please identify a pile from the table that you'd like to purchase: "))
|
||||||
|
self.__table.get_pile(pile_index).transfer_top_card(self.__discard)
|
||||||
|
self.__buys -= 1
|
||||||
|
|
||||||
|
def take_turn(self):
|
||||||
|
print("Deck Size: " + str(self.__deck.get_remaining()))
|
||||||
|
self.__print_hand()
|
||||||
|
self.__gain_turn_events()
|
||||||
|
self.take_action()
|
||||||
|
self.__print_discard()
|
||||||
|
self.__print_deck()
|
||||||
|
# self.give_reaction()
|
||||||
|
self.take_buy()
|
||||||
|
# self.discard_remaining_hand()
|
||||||
|
# self.draw_hand()
|
||||||
|
# self.__print_hand()
|
||||||
30
supply.py
Normal file
30
supply.py
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
class Supply:
|
||||||
|
def __init__(self):
|
||||||
|
self.__card = list()
|
||||||
|
|
||||||
|
def add_card(self, card):
|
||||||
|
self.__card.append(card)
|
||||||
|
|
||||||
|
def add_cards(self, card, n):
|
||||||
|
for i in range(n):
|
||||||
|
self.add_card(card)
|
||||||
|
|
||||||
|
def get_supply(self):
|
||||||
|
return self.__card
|
||||||
|
|
||||||
|
def transfer_top_card(self, recipient_supply):
|
||||||
|
self.transfer_card(len(self.__card) - 1, recipient_supply)
|
||||||
|
|
||||||
|
def transfer_card(self, n, recipient_supply):
|
||||||
|
transfer_card = self.__card.pop(n)
|
||||||
|
recipient_supply.add_card(transfer_card)
|
||||||
|
|
||||||
|
def get_card(self, n):
|
||||||
|
return self.__card[n]
|
||||||
|
|
||||||
|
def get_remaining(self):
|
||||||
|
return len(self.__card)
|
||||||
|
|
||||||
|
def print(self):
|
||||||
|
for c in self.__card:
|
||||||
|
print(c.identify())
|
||||||
60
table.py
Normal file
60
table.py
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
from trash import Trash
|
||||||
|
from pile import Pile
|
||||||
|
|
||||||
|
|
||||||
|
class Table:
|
||||||
|
def __init__(self):
|
||||||
|
self.__player = list()
|
||||||
|
self.__pile = list()
|
||||||
|
self.__trash = Trash()
|
||||||
|
self.__winner = None
|
||||||
|
self.__winning_score = 0
|
||||||
|
|
||||||
|
def add_player(self, p):
|
||||||
|
self.__player.append(p)
|
||||||
|
|
||||||
|
def get_player(self, n):
|
||||||
|
return self.__player[n]
|
||||||
|
|
||||||
|
def add_pile(self, card, n):
|
||||||
|
p = Pile()
|
||||||
|
p.add_cards(card, n)
|
||||||
|
self.__pile.append(p)
|
||||||
|
|
||||||
|
def get_piles(self):
|
||||||
|
return self.__pile
|
||||||
|
|
||||||
|
def get_pile(self, n):
|
||||||
|
return self.__pile[n]
|
||||||
|
|
||||||
|
def get_pile_index_of_card(self, card_name):
|
||||||
|
result = 0
|
||||||
|
for p in self.__pile:
|
||||||
|
if p.get_card_group().get_name() == card_name:
|
||||||
|
result = self.__pile.index(p)
|
||||||
|
return result
|
||||||
|
|
||||||
|
def are_there_any_empty_piles(self):
|
||||||
|
result = False
|
||||||
|
for p in self.__pile:
|
||||||
|
result = result or p.get_remaining() == 0
|
||||||
|
return result
|
||||||
|
|
||||||
|
def play(self):
|
||||||
|
turn = 0
|
||||||
|
# turn < 4 is for testing, otherwise endless as buying cards is not yet done
|
||||||
|
while not self.are_there_any_empty_piles() and turn < 4:
|
||||||
|
self.print()
|
||||||
|
self.__player[turn % len(self.__player)].take_turn()
|
||||||
|
turn += 1
|
||||||
|
else:
|
||||||
|
self.print()
|
||||||
|
for p in self.__player:
|
||||||
|
if p.get_score() > self.__winning_score:
|
||||||
|
self.__winning_score = p.get_score
|
||||||
|
self.__winner = p
|
||||||
|
|
||||||
|
def print(self):
|
||||||
|
print("Piles:")
|
||||||
|
for s in self.__pile:
|
||||||
|
print(s.get_card_group().identify() + ": " + str(s.get_remaining()))
|
||||||
Loading…
x
Reference in New Issue
Block a user