def endpoint_create_game(): try: game = find_game(request.json['town']['slug']) raise GameAlreadyExistException except GameDoesNotExistException: game = Game(request.json['town']['slug']) game.add_player(request.json['player']['name'], True) app_state[request.json['town']['slug']] = game return game.jversonify()
def load_games(): games = {} path = Game.filename() print('path is', path) for fn in os.listdir(path): print('filename is', fn) # TODO: check if os.path.isfile(os.path.join(path, name)) with open(os.path.join(path, fn), "r") as file: game = Game.from_hash(load(file)) games[game.game_id] = game print('loaded {}'.format(game.game_id)) return games
def increment_turn(source=sys.stdin, output=sys.stdout): """Entry point for the client ending their turn """ output.write('Content-Type: application/json\n\n') request = json.load(source) player_id = request["player_id"] games = get_games() with Player(player_id) as player: for game in games: if player.username in games[game]: game_id = game break with Game(game_id) as game: turn = game.current_turn if turn == len(game.players) - 1: turn = 0 else: turn += 1 game.current_turn = turn is_bankrupt(player_id) json.dump({"turn": "turn_over"}, output)
def delete_game(game_id): if game_id in GAMES: GAMES.pop(game_id) filepath = Game.filename(game_id) if os.path.exists(filepath): os.remove(filepath) return 'Ended game {}'.format(game_id), 200
def request_list_of_players(source=sys.stdin, output=sys.stdout): """Entry point for the service of requesting the list of players in a specfic game """ output.write('Content-Type: application/json\n\n') request = json.load(source) game_id = request["game_id"] game = Game(game_id) players = game.players json.dump(players, output)
def add_player(player_id, game_id): """Adds a player to a game.""" with Player(player_id) as player: with Game(game_id) as game: players = game.players players.append(player_id) game.players = players if str(game.state) == 'waiting': player.turn_position = len(game.players) - 1 else: pass
def new_game(game_id): if game_id in GAMES: return {'error': 'Game "{}" already exists'.format(game_id)}, 500 if len(GAMES) >= MAX_GAMES: return { 'error': 'Too many games: Please wait for another game to complete', 'game_over': True, }, 500 GAMES[game_id] = Game(game_id) print('[{}] NEW_GAME'.format(game_id)) return 'Created game {}'.format(game_id), 200
def new_game(self, level=1): """ new game Construct new labyrinth game. Args: level(int): Game level to construct. """ self.game = Game(program=self, level=level) self.labyrinth_interface = LabyrinthInterface(program=self) self.active_interface = self.labyrinth_interface
def player_roll_dice(source=sys.stdin, output=sys.stdout): """Rolls two dice for a player, appends there rolls to the database, updates their position and the current game turn. Checks if the user is in jail and does not increment their position if so. Also has a check for the board position 30(go to jail) and sends the player to the jail position if so. """ output.write('Content-Type: application/json\n\n') request = json.load(source) player_id = request["user_id"] number_of_squares = 40 pass_go_amount = 200 games = get_games() rolls = [] player_board_position = 0 with Player(player_id) as player: for game in games: if player.username in games[game]: game_id = game in_jail = player.jail_state break with Game(game_id) as game: if game.current_turn == player.turn_position: rolls = roll_two_dice() player.rolls.append(rolls) if in_jail == 'not_in_jail': player.board_position += sum(rolls) if player.board_position == 30: player.board_position = -1 player.jail_state = 'in_jail' else: if rolls[0] == rolls[1]: player.jail_state = 'not_in_jail' player.board_position = 10 if player.board_position >= number_of_squares: player.balance += pass_go_amount player.board_position -= number_of_squares player_board_position = player.board_position card_details = check_position(player_id, player_board_position) json.dump({"your_rolls": rolls, "card_details": card_details}, output)
def player_remove(player): """Player is removed from game with their status updated and appropriate changes commence (turn order, properties...) """ player_id = player.uid game_id = get_this_game(player_id) with Game(game_id) as game: # Removes player by id from the game's list of players game.players = [p for p in game.players if p != player_id] # This part receives properties owned by player by their # position and marks each property as 'unowned' property_positions = get_properties(player_id) for position in property_positions: with Property(position, game_id) as property_: property_.owner = 0 property_.state = 'unowned' property_.houses = 0 property_.hotels = 0 game.state = 'finished'
def __init__(self): self.event_listeners = [] self.actions = { "start": False, "exit": False, "resume": False, "end": False } self.current_event = None self.game_size = (Helpers.const["size"]["display_width"], Helpers.const["size"]["display_height"]) pygame.init() self.screen = pygame.display.set_mode(self.game_size) pygame.display.set_caption("Spacekatz") self.game = Game(self.game_size) self.name_menu = PlayerNameGameMenuUI(self) self.score_menu = ScoreGameMenuUI(self) self.start_menu = StartGameMenuUI(self) self.pause_menu = PauseGameMenuUI(self) self.start_menu.set_next_menus({ "Start": self.name_menu, "Scoreboard": self.score_menu }) self.score_menu.set_next_menus({ "Back": self.start_menu }) self.event_listeners.append(self.name_menu) self.event_listeners.append(self.score_menu) self.event_listeners.append(self.start_menu) self.event_listeners.append(self.pause_menu) self.start_menu.is_listening = True self.game_exit = False
class Spacekatz: def __init__(self): self.event_listeners = [] self.actions = { "start": False, "exit": False, "resume": False, "end": False } self.current_event = None self.game_size = (Helpers.const["size"]["display_width"], Helpers.const["size"]["display_height"]) pygame.init() self.screen = pygame.display.set_mode(self.game_size) pygame.display.set_caption("Spacekatz") self.game = Game(self.game_size) self.name_menu = PlayerNameGameMenuUI(self) self.score_menu = ScoreGameMenuUI(self) self.start_menu = StartGameMenuUI(self) self.pause_menu = PauseGameMenuUI(self) self.start_menu.set_next_menus({ "Start": self.name_menu, "Scoreboard": self.score_menu }) self.score_menu.set_next_menus({ "Back": self.start_menu }) self.event_listeners.append(self.name_menu) self.event_listeners.append(self.score_menu) self.event_listeners.append(self.start_menu) self.event_listeners.append(self.pause_menu) self.start_menu.is_listening = True self.game_exit = False def play(self): self.starfield_backgr = StarField(self.screen, 250) clock = pygame.time.Clock() kat_name = self.name_menu.current_input self.kat_group = Group() self.bullet_group = Group() self.bird_group = Group() kat_back = Kat(Coords(200, 550), kat_name, self.game.board) self.kat = KatUI(self.screen, kat_back, self.bullet_group) self.kat.add(self.kat_group) start_level = self.game.start(self.screen, self.bullet_group, self.bird_group) for bird_back in start_level.get_enemies(): new_bird_ui = BirdUI( self.screen, bird_back, self.bullet_group) new_bird_ui.add(self.bird_group) while not self.game_exit: clock.tick(60) self.screen.fill(Helpers.const["color"]["black"]) # only the ones that are currently listening # will be displayed self.start_menu.display() self.score_menu.display() self.name_menu.display() self.pause_menu.display() for event in pygame.event.get(): if event.type == pygame.QUIT: self.game_exit = True else: self.current_event = event for listener in self.event_listeners: listener.notify(event) for action_name, value in self.actions.items(): if value: getattr(self, action_name + "_action")() pygame.display.flip() def start_action(self): self.screen.fill(Helpers.const["color"]["black"]) self.starfield_backgr.redraw_stars() self.kat.handle_event(self.current_event) Helpers.display_message(self.screen, "Score: " + str(self.kat.kat.score), 80, -200) Helpers.display_message(self.screen, "Health: " + str(self.kat.kat.health), 80, 200) Helpers.display_message(self.screen, self.kat.kat.name, 50, 50) self.kat_group.update(1) self.bullet_group.update(0.1) self.bird_group.update(0.5) self.kat_group.draw(self.screen) self.bird_group.draw(self.screen) self.bullet_group.draw(self.screen) pygame.display.flip() def pause_action(self): pass def resume_action(self): pass def end_action(self): pass def exit_action(self): print("Game is exited") self.game_exit = True def next_level_action(self): pass
def start_sse_stream(output_stream=sys.stdout): """Generate a stream of server-sent events according to state changes. This function is activated by making a request to the JavaScript function "initialiseEventSource()" which is located in "sse.js". This operation is performed by the JavaScript waitingGame function, and hence, other JavaScript code need only "get" a reference to the EventSource object (by calling "getEventSource()" from "sse.js"). Reads in the game id, and repeatedly does each of the following: 1) Check whose turn it is. 2) Check if any new players have joined the waiting game lobby. 3) Check if any of the players' balances have changed in a game. 4) Check if any of the players' positions have changed in a game. 5) Check if the specified game's status has changed to "playing". """ # The following headers are compulsory for SSE. output_stream.write('Content-Type: text/event-stream\n') output_stream.write('Cache-Control: no-cache\n') output_stream.write('\n') # Read in the game id from standard input (aka. FieldStorage) and create # an empty dictionary of current players, positions, balances, new # players, new positions, new balances and turn orders. All the "new" # dicts will be populated with the most up to date data from the # **database**, while non-"new" dicts will be populated only after a # comparison between it and the corresponding "new" dict has been made. input_data = FieldStorage() game_id = input_data.getfirst('game') last_game_state = "waiting" players = {} positions = {} balances = {} new_players = {} new_positions = {} new_balances = {} turn = None turn_order = {} jailed_players = {} new_jailed_players = {} push_initial_user_details = True houses = {} property_ownership = {} # These statements are executed constantly once the first request to this # function is made. while True: # Create a Game object representing the game in the database. # This can be thought of as a "pointer" to the appropriate game in the # database. game = Game(game_id) # Go through each player in the game and populate the "new" # dictionaries with user_id (aka. player_id) as the key, and # username/position/balance/turn-order as the value. # These are the latest values retrieved from the database. for player in map(Player, game.players): new_players[player.uid] = player.username new_jailed_players[player.uid] = player.jail_state new_positions[player.uid] = player.board_position new_balances[player.uid] = player.balance turn_order[player.uid] = player.turn_position # Assign the current (aka. non-new) dictionaries to the value of the # "new" (aka. latest) dictionaries, after calling the appropriate # comparison function to determine whether an event should be # generated. turn = check_new_turn(output_stream, turn, game.current_turn, turn_order) players = check_new_players(output_stream, players, new_players) balances = check_new_balances(output_stream, balances, new_balances) jailed_players = check_new_jailed_players(output_stream, jailed_players, new_jailed_players) positions = check_new_positions(output_stream, positions, new_positions, new_jailed_players) houses = check_property_houses(output_stream, game_id, houses) property_ownership = check_property_ownership( output_stream, game_id, property_ownership, ) # Pushes data to update the players info table on game start if push_initial_user_details and last_game_state == "playing": push_initial_user_details = False start_game_push(output_stream, turn_order) # Call function to check the current state of this game. # A game state may be "waiting" or "playing". last_game_state = check_game_playing_status(output_stream, game, last_game_state) time.sleep(3) # Flush standard out which forcefully sends everything that might be # buffered in standard out to the client. No need to worry about tech # details too much, it's just standard SSE procedure! output_stream.flush()
async def handler(websocket, path): """ Handler for each client connection. :websocket: object to communicate with client :path: path of the url at which player connected from """ await asyncio.sleep(1) global idCount global games global gameId idCount += 1 playerId = (idCount - 1) % NUMBER_OF_PLAYERS + 1 player = Player(playerId) if idCount % NUMBER_OF_PLAYERS == 1: gameId += 1 games[gameId] = Game(gameId, NUMBER_OF_PLAYERS) print("Creating a new game...") else: print("joining to existing game", gameId) await websocket.send("Attempting connection with player #" + str(player.id)) name = await websocket.recv() if name.split(",")[0] != "name": await websocket.send("Expected user to first send name.") print("Loosing connection for player") if idCount % NUMBER_OF_PLAYERS == 1: del games[gameId] idCount -= 1 return game = games[gameId] player_name = ''.join(name.split(",")[1:]) game.add_player(player) game.set_name(player, player_name) await websocket.send("0,waiting for players") # await asyncio.get_event_loop().run_in_executor(None, functools.partial(start_game, game = game)) task = asyncio.create_task(start_game_task(websocket=websocket, game=game)) await task if game.started: await websocket.send("1,Game starting") await websocket.send("2," + game.get_category(player)) async for message in websocket: await message_handler(websocket, message, player, game) if player.finished: break if game.all_finished(): break ## if any player looses connection when trying to start game if not game.started: pass ## we should add handling for this game.finished(player) if not game.all_finished(): await asyncio.get_event_loop().run_in_executor( None, functools.partial(finish_game, game=game)) print("For player", idCount, "printed") await websocket.send("4," + str(NUMBER_OF_PLAYERS) + "," + game.get_info()) try: del games[gameId] idCount -= NUMBER_OF_PLAYERS except KeyError: print("failed to remove") pass
from backend.game import Game game = Game('Swiebodzin') game.add_player('sasanka') game.add_player('kaktus') game.add_player('boletz') game.add_player('pizdziec') game.add_player('pusi_crussher') game.start_game() mafioso_number = len( [p for p in game.town.players.values() if p.character == 'mafia']) assert mafioso_number == 1, 'Game with five players should start with 1 mafioso character, not {0}.'.format( mafioso_number)
from flask import Flask from opentok import OpenTok, MediaModes import os from backend.game import Game app = Flask(__name__) app.config['SECRET_KEY'] = 'a76d96d18217941ed34797f1733e1cdc' try: api_key = os.environ["API_KEY"] api_secret = os.environ["API_SECRET"] except Exception: raise Exception( "You must define API_KEY and API_SECRET environment variables") opentok = OpenTok(api_key, api_secret) session = opentok.create_session(media_mode=MediaModes.routed) the_game = Game()
def activate_card(player_id, game_id, card_landed_on): # pylint: disable=too-many-locals # pylint: disable=too-many-branches """Read a chance or community chest card that the player landed on. Arguments: player_id: An int representing the current player id. game_id: An int representing the current game id. card_landed_on: An int representing the type of card the player has activated """ # Check if card is chance or community chest if card_landed_on == "chest": card_table_id = randint(0, LAST_CHEST_INDEX_IN_TABLE) else: card_table_id = randint(LAST_CHEST_INDEX_IN_TABLE + 1, LAST_CHANCE_INDEX_IN_TABLE) # Dive into database to get the card details card_details = get_card_details(card_table_id) # Check what type of chance card it is card_type = card_details["operation"] # Get the card description, this is what's sent to the client card_description = card_details["description"] # Get value # This card_value is unique in that it represents different things # depending on the card_type. See below comments for more information card_value = card_details["operation_value"] # If it's a "move_specific" type of chance card if card_type == "move_specific": # Update the player position in players table with "chance" value with Player(player_id) as player: # Check if the card wants the player to move back some spaces # or simply *jump* to a specific space on the board if card_value < 0: # The card value here indicates how many spaces to move back player.board_position += card_value else: # The card value here indicates the board position to move to player.board_position = card_value # If it's a "pay_per_house" type of chance card elif card_type == "pay_per_house": # Variable to store total houses owned (hotels are worth four houses) total_houses = 0 # Get a *list* of all properties owned by the current player this_player_properties = get_properties(player_id) # Go through each property for property_position in this_player_properties: with Property(game_id, property_position) as property_: total_houses += property_.houses total_houses += (property_.hotels * 4) # The card_value here indicates how much to pay for a single house to_pay = total_houses * card_value with Player(player_id) as player: player.balance -= to_pay # If it's a "get_money" type of chance card elif card_type == "get_money": with Player(player_id) as player: # The card_value here indicates how much money to add to balance player.balance += card_value # If it's a "pay_bank" type of chance card elif card_type == "pay_bank": with Player(player_id) as player: # The card_value here indicates how much to deduct from balance player.balance -= card_value elif card_type == "collect_from_opponents": # Get a list of players in this game players_in_game = [] with Game(game_id) as game: players_in_game = game.players # Iterate through each player and deduct from their balance if they # are not the current (aka. this) player for id_ in players_in_game: with Player(id_) as player: if int(player_id) != id_: # card_value here indicates the amount to deduct from # opponent's balance player.balance -= card_value else: # Add to this player's balance the total amount deducted # from the opponents. # Note that the amount to add to this player's balance can # be found by simply multiplying the amount to deduct per # opponent (i.e. card_value) by the *number* of opponents player.balance += (card_value * (len(players_in_game) - 1)) return card_description
""" Run this file to play Piously """ from backend.game import Game if __name__ == "__main__": piously = Game("Dark") piously.play()