Exemple #1
0
def main():
    # set up window display stuff
    pygame.display.set_caption('Catan')
    screen = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))

    game_board = GameBoard(300, 100, WINDOW_WIDTH / 2, 100)

    running = True

    time_between_frames = 1 / FRAMES_PER_SECOND

    # ~~~~~ MAIN GAME LOOP ~~~~~
    while running:
        screen.fill((100, 100, 200))
        start_time = time.time()

        game_board.draw(screen)
        game_board.hex_board.select(game_board.hex_board.roads)

        pygame.display.flip()

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False

        sleep_time = (start_time + time_between_frames) - time.time()
        if sleep_time > 0:
            time.sleep(sleep_time)
class Game:
    def __init__(self):
        self.__running = False
        self.screen = pygame.display.set_mode(
            (Consts.WINDOW_WIDTH, Consts.WINDOW_HEIGHT))
        self.__clock = pygame.time.Clock()  # frame clock
        self.__game_board = GameBoard()
        self.player = Player()
        self.control_panel = ControlPanel(self.player)
        self.caretaker = Caretaker(self.player)

    def start_game(self):
        pygame.display.set_caption("Silesian Game")
        self.__running = True
        self.__game_loop()

    def __game_loop(self):
        while self.__running:
            self.__clock.tick(Consts.FPS)
            self.__key_control()
            self.__draw()
            self.player.income_gold()
            pygame.display.update()

    def __draw(self):
        self.control_panel.draw(self.screen, self.player.get_gold())
        self.__game_board.draw(self.screen)
        self.player.draw_buildings(self.screen)

    def __build(self, building_type):
        if building_type == 0:
            if self.player.get_gold() >= Consts.WOODCUTTERS_HUT_COST:
                self.caretaker.store_snapshot()
                self.player.add_building(
                    WoodcuttersHut(self.player.next_building_position()))
                self.player.spend_gold(Consts.WOODCUTTERS_HUT_COST)
            else:
                print("Dont have enough gold!")
        elif building_type == 1:
            if self.player.get_gold() >= Consts.QUARRY_COST:
                self.caretaker.store_snapshot()
                self.player.add_building(
                    Quarry(self.player.next_building_position()))
                self.player.spend_gold(Consts.QUARRY_COST)
            else:
                print("Dont have enough gold!")
        elif building_type == 2:
            if self.player.get_gold() >= Consts.SAWMILL_COST:
                self.caretaker.store_snapshot()
                self.player.add_building(
                    Sawmill(self.player.next_building_position()))
                self.player.spend_gold(Consts.SAWMILL_COST)
            else:
                print("Dont have enough gold!")
        elif building_type == 3:
            if self.player.get_gold() >= Consts.GOLD_MINE_COST:
                self.caretaker.store_snapshot()
                self.player.add_building(
                    GoldMine(self.player.next_building_position()))
                self.player.spend_gold(Consts.GOLD_MINE_COST)
            else:
                print("Dont have enough gold!")
        elif building_type == 4:
            if self.player.get_gold() >= Consts.GOLD_MINT_COST:
                self.caretaker.store_snapshot()
                self.player.add_building(
                    GoldMint(self.player.next_building_position()))
                self.player.spend_gold(Consts.GOLD_MINT_COST)
            else:
                print("Dont have enough gold!")

    def __key_control(self):
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                self.__running = False
            elif event.type == pygame.MOUSEBUTTONDOWN:
                building_type = self.__is_onclick(event.pos)
                if building_type in [0, 1, 2, 3, 4]:
                    if self.player.get_buildings_length(
                    ) >= Consts.NUMBER_OF_ROWS * Consts.NUMBER_OF_COLUMNS:
                        print("Cant build more!")
                        continue
                    self.__build(building_type)
                elif building_type == 5:
                    self.caretaker.undo()
                elif building_type == 6:
                    self.caretaker.redo()

    @staticmethod
    def __is_onclick(mouse_position):
        if (Consts.PANEL_BUILDING_0_POSITION[0] < mouse_position[0] <
                Consts.PANEL_BUILDING_0_POSITION[0] + Consts.ICON_SIZE
                and Consts.PANEL_BUILDING_0_POSITION[1] < mouse_position[1] <
                Consts.PANEL_BUILDING_0_POSITION[1] + Consts.ICON_SIZE):
            return 0
        elif (Consts.PANEL_BUILDING_1_POSITION[0] < mouse_position[0] <
              Consts.PANEL_BUILDING_1_POSITION[0] + Consts.ICON_SIZE
              and Consts.PANEL_BUILDING_1_POSITION[1] < mouse_position[1] <
              Consts.PANEL_BUILDING_1_POSITION[1] + Consts.ICON_SIZE):
            return 1
        elif (Consts.PANEL_BUILDING_2_POSITION[0] < mouse_position[0] <
              Consts.PANEL_BUILDING_2_POSITION[0] + Consts.ICON_SIZE
              and Consts.PANEL_BUILDING_2_POSITION[1] < mouse_position[1] <
              Consts.PANEL_BUILDING_2_POSITION[1] + Consts.ICON_SIZE):
            return 2
        elif (Consts.PANEL_BUILDING_3_POSITION[0] < mouse_position[0] <
              Consts.PANEL_BUILDING_3_POSITION[0] + Consts.ICON_SIZE
              and Consts.PANEL_BUILDING_3_POSITION[1] < mouse_position[1] <
              Consts.PANEL_BUILDING_3_POSITION[1] + Consts.ICON_SIZE):
            return 3
        elif (Consts.PANEL_BUILDING_4_POSITION[0] < mouse_position[0] <
              Consts.PANEL_BUILDING_4_POSITION[0] + Consts.ICON_SIZE
              and Consts.PANEL_BUILDING_4_POSITION[1] < mouse_position[1] <
              Consts.PANEL_BUILDING_4_POSITION[1] + Consts.ICON_SIZE):
            return 4
        elif (Consts.BACK_BUTTON_POSITION[0] < mouse_position[0] <
              Consts.BACK_BUTTON_POSITION[0] + Consts.ICON_SIZE
              and Consts.BACK_BUTTON_POSITION[1] < mouse_position[1] <
              Consts.BACK_BUTTON_POSITION[1] + Consts.ICON_SIZE):
            return 5
        elif (Consts.FORWARD_BUTTON_POSITION[0] < mouse_position[0] <
              Consts.FORWARD_BUTTON_POSITION[0] + Consts.ICON_SIZE
              and Consts.FORWARD_BUTTON_POSITION[1] < mouse_position[1] <
              Consts.FORWARD_BUTTON_POSITION[1] + Consts.ICON_SIZE):
            return 6
        else:
            return 7
Exemple #3
0
class Game(object):
    """
    Responsible for managing the flow of a game and all of its entities.
    """
    def __init__(self):
        # set up game parameters and initialize data structures
        logging.debug('initializing')
        self.player = Player()
        self.game_board = GameBoard()

    # The current round of play
    current_round = 1

    # The number of rounds played before the game ends
    GAME_LENGTH = 14

    HARVEST_ROUNDS = frozenset([4, 7, 9, 11, 13, 14])

    def run(self):
        # execute the iterative flow of the game
        while self.current_round <= self.GAME_LENGTH:
            self.player.update()
            self.game_board.update()
            print 'Round: %s' % self.current_round
            while self.player.has_idle_family_members:
                action = self.get_action_input()
                if not self.game_board.available_actions[action].is_occupied:
                    try:
                        self.game_board.available_actions[action].take(
                            self.player)
                    except CancelledActionException as e:
                        if e.message:
                            print e.message
                        continue
                    self.player.send_family_member_to_work()
                else:
                    print 'The %s space is already occupied. Type -a to see the board.' % action
            if self.current_round in self.HARVEST_ROUNDS:
                self.player.field.harvest(self.player)
            self.current_round += 1
        self.end()

    def end(self):
        # calculate score, print results
        score = self.calculate_final_score()
        print 'Your score was: %s' % score

    def calculate_final_score(self):
        # calculate the player's final score
        logging.debug('calculating final score for player')
        score = 0  # get stuff here
        return score

    def get_action_input(self):
        action_input = raw_input('Please type an action: ').lower()
        if action_input in self.game_board.available_actions.keys():
            return action_input
        elif action_input == '-p':
            self.player.draw()
        elif action_input == '-f':
            self.player.field.draw()
        elif action_input == '-a':
            self.game_board.draw()
        else:
            print 'invalid action: %s' % action_input
            print 'type -a to see a list of available actions, -p to see your resources, -f to see your field'
        return self.get_action_input()
Exemple #4
0
from readchar import readchar

from game_board import GameBoard

if __name__ == '__main__':
    game_board = GameBoard(20, 10)
    print("WASD to move.")
    print("SPACE to shoot.")
    print("x to close.")
    print("Push any key to start!")
    while True:
        user_input = readchar().decode(encoding='utf-8')
        game_board.update(user_input)
        game_board.draw()
        if user_input == "x":
            exit(0)
Exemple #5
0
class CatanClient(ConnectionListener):
    """Client for Catan game. Manages all displays"""
    def __init__(self, host='localhost', port=4200):
        pygame.init()

        self.game_board = None
        self.screen = None

        self.game_id = None

        self.my_player = None

        self.state = GameState.WAITING_FOR_PLAYERS

        self.state_functions = {
            GameState.SELECT_SETTLEMENT: self.select_settlement,
            GameState.SELECT_ROAD: self.select_road,
            GameState.ROLL_DICE_WAIT: self.roll_dice_wait,
            GameState.ROLL_DICE_STOP: self.roll_dice_stop
        }

        self.Connect((host, port))
        self.server_response = False
        while not self.server_response:
            self.pump()
            sleep(0.01)

        print('You have connected to the central server!')

        # need to keep asking user
        self.accepted_by_server = False
        while not self.accepted_by_server:
            will_host = OptionGetter.hosting_preference()
            game_options = OptionGetter.game_specs()
            self.num_players = game_options['num_players']

            # send the server these options
            self.send({
                'action': 'check_hosting',
                'host': will_host,
                'options': game_options
            })

            # wait on the server for a response
            self.server_response = False
            print('Waiting on server...')
            while not self.server_response:
                self.pump()
                sleep(0.01)

        print('Ready to play at game: ' + str(self.game_id))

        # user must now pick a username and color that are unique from
        # other players already in the game
        self.accepted_by_server = False
        while not self.accepted_by_server:
            username, color = OptionGetter.user_and_color()
            self.my_player = ClientMyPlayer(username, color)

            # send server this selection
            self.send({
                'action': 'user_color_selection',
                'username': username,
                'color': color
            })

            # wait on server for a response
            self.server_response = False
            print('Waiting on server...')
            while not self.server_response:
                self.pump()
                sleep(0.01)

        self.screen = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))
        # the user's game specs have been accepted by the server.
        # must wait until the max # of players has been reached

    # to improve readability. adds the game id to what is being sent to
    # the server
    def send(self, message):
        if self.game_id is not None:
            message['game_id'] = self.game_id
        connection.Send(message)

    # the server is informing the client that they have connected
    def Network_init(self, data):
        self.server_response = True
        print('Connected to the server...')

    # receive message from server about whether the desired game specifications
    # exist. (note: if user is trying to host, their request will always be
    # accepted)
    def Network_check_hosting(self, data):
        self.server_response = True
        if data['accepted']:
            self.accepted_by_server = True
            self.game_id = data['game_id']

    # the server is informing the client if their username / color choices
    # have already been taken
    def Network_check_user_color(self, data):
        self.server_response = True
        accept_username = data['accept_username']
        accept_color = data['accept_color']
        if accept_username and accept_color:
            print('Username and color have been accepted!')
            # add the client's own player to the sidebar
            self.accepted_by_server = True
            self.game_board.sidebar.add_player(self.my_player.username,
                                               self.my_player.color)
            pygame.display.set_caption('Settlers of Catan')
        elif accept_username and not accept_color:
            print('Color was already taken by another player')
        elif not accept_username and accept_color:
            print('Username was already taken by another player')
        else:
            print('Username and color already taken by another player, lmao')

    # the server is informing the client of the players who are already in the game
    def Network_current_players(self, data):
        for player in data['players']:
            self.game_board.sidebar.add_player(player['username'],
                                               player['color'])
            print('I have been informed of {}, who is {}'.format(
                player['username'], player['color']))

    # the server is informing the client of a new player who has joined the game
    def Network_new_player(self, data):
        self.game_board.sidebar.add_player(data['username'], data['color'])
        print('I have been informed of {}, who is {}'.format(
            data['username'], data['color']))

    # the server is giving the client the game board layout
    def Network_game_board(self, data):
        layout = data['layout']
        for item in layout:
            print(item)
        self.game_board = GameBoard(200, 200, layout, self.num_players)

    # network signals from here below are those received during actually game-play
    # and mostly just change the client's state or screen. they are paired w/ the
    # appropriate state function

    # FROM SERVER
    # waiting on another player; nothing for the client to do
    def Network_wait(self, data):
        self.state = GameState.WAIT
        print('Waiting on player {}'.format(data['cur_player']))

    # FROM SERVER
    # client must select a settlement
    def Network_select_settlement(self, data):
        self.state = GameState.SELECT_SETTLEMENT
        print('Please select a settlement')

    # FROM SERVER
    # a new settlement has been created
    def Network_new_settlement(self, data):
        settlement_index = data['settlement']
        color = data['color']
        self.game_board.new_settlement(settlement_index, color)

    # FROM SERVER
    # a new road has been created
    def Network_new_road(self, data):
        road_index = data['road']
        color = data['color']
        self.game_board.new_road(road_index, color)

    # FROM SERVER
    # client must select a road
    def Network_select_road(self, data):
        self.state = GameState.SELECT_ROAD
        print('Please select a road')

    # FROM SERVER
    # client made invalid selection
    def Network_invalid(self, data):
        print('Invalid {} selection, please try again'.format(data['message']))

    # FROM SERVER
    # the user's resources have changed; update them
    def Network_update_resources(self, data):
        pass

    # FROM SERVER
    # clients begin rolling dice
    def Network_wait_dice(self, data):
        self.state = GameState.ROLL_DICE_WAIT
        self.dice_roll_count = 0
        dice_stopper = data['roller']
        print('Waiting for {} to stop the dice...'.format(dice_stopper))

    def Network_roll_dice(self, data):
        self.state = GameState.ROLL_DICE_STOP
        self.dice_roll_count = 0
        print('Please click to stop the dice')

    # FROM SERVER
    # result of dice roll
    def Network_dice_result(self, data):
        self.state = GameState.WAIT
        left = data['left']
        right = data['right']
        self.game_board.dice.set(left, right)
        print('Dice result: {} and {}'.format(left + 1, right + 1))

    # GAME STATE
    # the user needs to select a road
    def select_settlement(self, mouse_pos, mouse_click):
        selection = self.game_board.select_settlement(mouse_pos)
        if mouse_click and selection is not None:
            # user has selected a settlement, send selection to server
            self.send({'action': 'select_settlement', 'settlement': selection})

    # GAME STATE
    # the user needs to select a road
    def select_road(self, mouse_pos, mouse_click):
        selection = self.game_board.select_road(mouse_pos)
        if mouse_click and selection is not None:
            # user has selected a road, send selection to server
            self.send({'action': 'select_road', 'road': selection})

    # GAME STATE
    # the user must wait for the current player to stop the dice
    # in the meantime, let the user observe the beautifully crafted dice at the top of the screen
    def roll_dice_wait(self, mouse_pos, mouse_click):
        if self.dice_roll_count == 16:
            self.game_board.dice.next()
            self.dice_roll_count = 0
        self.dice_roll_count += 1

    # GAME STATE
    # the user must click to stop the dice
    def roll_dice_stop(self, mouse_pos, mouse_click):
        if self.dice_roll_count == 16:
            self.game_board.dice.next()
            self.dice_roll_count = 0
        self.dice_roll_count += 1

        if mouse_click:
            # user wants to stop the dice
            self.send({'action': 'stop_dice'})

    def draw(self, screen):
        self.game_board.draw(screen)

    def update(self):
        # do all management of key presses / mouse info here
        mouse_click = False
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                exit(1)
            elif event.type == pygame.MOUSEBUTTONUP:
                # mouse has been clicked!
                mouse_click = True

        mouse_pos = pygame.mouse.get_pos()

        if self.state != GameState.WAITING_FOR_PLAYERS and self.state != GameState.WAIT:
            self.state_functions[self.state](mouse_pos, mouse_click)

        self.screen.fill((100, 100, 250))
        self.draw(self.screen)
        pygame.display.flip()

    # if self.Pump() is called twice in a row events will occur twice,
    # which is bad. use this instead
    def pump(self):
        connection.Pump()
        self.Pump()
Exemple #6
0
class Game(object):
    def __init__(self, manager, white_player='human', black_player='human'):

        # game state members
        self.game_manager = manager
        self.game_running = False
        self.needs_redraw = True
        self.screen = None
        self.clock = pygame.time.Clock()

        # game components
        self.game_logic = GameLogic(self)
        self.game_grid = GameGrid(self)
        self.game_board = None

        self.white_player = None
        self.black_player = None
        self.initialize_players(white_player, black_player)

        self.turn_manager = TurnManager(self)
        self.highlighter = Highlighter(self)
        self.logger = Logger(self)

        self.buttons = {}

    def init(self):

        self.screen = pygame.display.get_surface()
        self.game_running = True

        self.screen.fill(BLACK)

        # initialize game components
        self.game_board = GameBoard(self, self.game_grid)
        self.highlighter.init()
        self.initialize_buttons()

    def initialize_buttons(self):

        restart_button = Button(restart_coord, 'Restart', self.restart,
                                restart_anchor, False)
        end_button = Button(end_coord, 'End Game', self.exit_game, end_anchor)
        self.buttons['restart'] = restart_button
        self.buttons['end'] = end_button

    def initialize_players(self, white, black):

        players = []
        sides = ['white', 'black']
        constructors = []
        for p_type in (white, black):
            if p_type == 'human':
                constructors.append(Player)
            else:
                constructors.append(AIPlayer)

        for i in (0, 1):
            players.append(constructors[i](self, sides[i]))

        self.white_player = players[0]
        self.black_player = players[1]

    # main game loop
    def main(self):

        while self.game_running:

            self.handle_input()
            self.run_logic()
            if self.needs_redraw:
                self.draw_all()
                self.update_display()
                self.reset_redraw()
            self.tick()

    def handle_input(self):

        for event in pygame.event.get():

            if event.type == QUIT:
                self.exit_program()

            elif event.type == MOUSEBUTTONDOWN:

                if self.active_player.is_human() and self.mouse_over_grid():
                    self.active_player.try_to_place_piece(
                        self.mouse_grid_position())
                else:
                    for button in self.buttons.itervalues():
                        if button.active and button.mouse_is_over():
                            button.on_click()

    @property
    def active_player(self):
        return self.turn_manager.active_player

    def mouse_over_grid(self):
        mx, my = pygame.mouse.get_pos()
        return my > BOARD_Y_OFFSET

    def mouse_grid_position(self):
        mouse_pos = pygame.mouse.get_pos()
        return self.game_grid.translate_mouse_to_grid_coord(mouse_pos)

    def exit_game(self):
        self.game_running = False

    def exit_program(self):
        self.game_running = False
        self.game_manager.exit_game()
        print 'here'

    def run_logic(self):
        self.turn_manager.run()
        if not self.active_player.is_human(
        ) and self.turn_manager.game_running:
            self.active_player.run_logic()

    def draw_all(self):
        self.game_board.draw(self.screen)
        self.highlighter.draw(self.screen)
        self.logger.draw_scores(self.screen)
        self.logger.draw_log(self.screen)

        for button in self.buttons.itervalues():
            if button.active:
                button.draw(self.screen)

    def update_display(self):
        pygame.display.update()

    def request_redraw(self):
        self.needs_redraw = True

    def reset_redraw(self):
        self.needs_redraw = False

    def tick(self):
        self.clock.tick(FPS)

    def black_score(self):
        return self.game_grid.get_score(BLACK_PIECE)

    def white_score(self):
        return self.game_grid.get_score(WHITE_PIECE)

    def activate_button(self, key):
        self.buttons[key].set_active()

    def hide_button(self, key):
        self.buttons[key].hide()

    def restart(self):
        self.game_grid.reset_state()
        self.turn_manager.reset_state()
        self.request_redraw()
        self.hide_button('restart')