Implement mouse clicking for playing cards

master
En Yi 2019-06-11 19:10:04 +01:00
parent 36b0594106
commit ba88887a72
3 changed files with 112 additions and 37 deletions

24
main.py
View File

@ -37,16 +37,6 @@ class GameScreen(view.PygView):
pygame.display.flip() pygame.display.flip()
def process_events(self):
for event in pygame.event.get():
if event.type == pygame.QUIT:
self.running = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
self.running = False
if event.key == pygame.K_p:
if not self.table.ongoing:
self.table.ongoing = True
#def get_player_inputs(self): #def get_player_inputs(self):
# while self.running: # while self.running:
@ -58,10 +48,20 @@ class GameScreen(view.PygView):
self.running = True self.running = True
#self.player_thread.start() #self.player_thread.start()
while self.running: while self.running:
self.process_events()
all_events = pygame.event.get()
for event in all_events:
if event.type == pygame.QUIT:
self.running = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
self.running = False
if event.key == pygame.K_p:
if not self.table.ongoing:
self.table.ongoing = True
if self.table.ongoing: if self.table.ongoing:
self.table.continue_game() self.table.continue_game(all_events)
#if not self.player_commands.empty(): #if not self.player_commands.empty():
# player_cmd = self.player_commands.get() # player_cmd = self.player_commands.get()
# print("Player Command Received: " + player_cmd) # print("Player Command Received: " + player_cmd)

View File

@ -1,5 +1,6 @@
import cards import cards
import pprint import pprint
import pygame
from game_consts import GameState, PlayerRole, STARTING_HAND from game_consts import GameState, PlayerRole, STARTING_HAND
@ -37,11 +38,12 @@ class Player(cards.Deck):
ai_comp.connect_to_player(self) ai_comp.connect_to_player(self)
self.selectable = False self.selectable = False
def make_decision(self, game_state, sub_state): def make_decision(self, game_state, sub_state, game_events=None):
""" """
The player will need to make a decision depending on the game state and sub-state The player will need to make a decision depending on the game state and sub-state
:param game_state: Current game state :param game_state: Current game state
:param sub_state: Sub-state which affects the output for the current game state :param sub_state: Sub-state which affects the output for the current game state
:param game_events: Pygame events
:return: For Bidding: Either a bid or a partner call, int :return: For Bidding: Either a bid or a partner call, int
For Playing: A Card For Playing: A Card
For Reshuffle: bool, True to reshuffle, False otherwise For Reshuffle: bool, True to reshuffle, False otherwise
@ -65,7 +67,7 @@ class Player(cards.Deck):
play = self.AI.make_a_play(sub_state) play = self.AI.make_a_play(sub_state)
[_, pos] = self.check_card_in(play) [_, pos] = self.check_card_in(play)
return self.remove_card(pos) return self.remove_card(pos)
return self.make_a_play(sub_state) return self.make_a_play(sub_state, game_events=game_events)
def make_a_bid(self): def make_a_bid(self):
""" """
@ -111,7 +113,7 @@ class Player(cards.Deck):
else: else:
print("Invalid card call") print("Invalid card call")
def make_a_play(self, substate): def make_a_play(self, substate, game_events=None):
""" """
The procedure to make a play in a round The procedure to make a play in a round
:return: A valid Card :return: A valid Card
@ -124,10 +126,7 @@ class Player(cards.Deck):
else: else:
play = cards.convert_input_string(play) play = cards.convert_input_string(play)
if play > 0: if play > 0:
if substate == 0: valid = self.check_for_valid_plays(play, substate == 0)
valid = self.check_for_valid_plays(play, True)
else:
valid = self.check_for_valid_plays(play, False)
if valid: if valid:
[_, pos] = self.check_card_in(play) [_, pos] = self.check_card_in(play)
@ -189,8 +188,47 @@ class MainPlayer(Player):
self.AI = ai_component self.AI = ai_component
self.table_status = None # This is found in Table and updated through Table self.table_status = None # This is found in Table and updated through Table
self.selectable = True self.selectable = True
self.left_mouse_down = False
self.double_clicking = False
self.double_click_event = pygame.USEREVENT + 1
self.double_click_timing = 300
def make_a_play(self): def make_a_play(self, substate, game_events=None):
pass card = None
if game_events:
for event in game_events:
mouse_clicks = event.type == pygame.MOUSEBUTTONDOWN
if self.left_mouse_down and not mouse_clicks:
print('mouse click')
mouse_pos = pygame.mouse.get_pos()
if self.rect.collidepoint(mouse_pos):
reselect = self.get_selected_card(mouse_pos)
if self.selected_card >= 0 and not reselect:
card = 1
if self.double_clicking:
pygame.time.set_timer(self.double_click_event, 0)
print('Double clicked')
if reselect:
card_value = self.cards[self.selected_card].value
if self.check_for_valid_plays(card_value, substate == 0):
card = self.remove_selected_card()
self.deselect_card()
self.double_clicking = False
else:
self.double_clicking = True
pygame.time.set_timer(self.double_click_event, self.double_click_timing)
if reselect:
self.deselect_card()
card = 1
if event.type == self.double_click_event:
pygame.time.set_timer(self.double_click_event, 0)
self.double_clicking = False
print('double click disabled')
self.left_mouse_down = mouse_clicks
return card

View File

@ -142,11 +142,19 @@ class Table:
reveal_mode = cards.DeckReveal.HIDE_ALL reveal_mode = cards.DeckReveal.HIDE_ALL
if i == 0 or view_all_cards: if i == 0 or view_all_cards:
reveal_mode = cards.DeckReveal.SHOW_ALL reveal_mode = cards.DeckReveal.SHOW_ALL
if i == 0:
self.players.append(players.MainPlayer(playerx[i], playery[i],
l_deck, w_deck,
spacing, vert_orientation=vert,
deck_reveal=reveal_mode))
else:
self.players.append(players.Player(playerx[i], playery[i], self.players.append(players.Player(playerx[i], playery[i],
l_deck, w_deck, l_deck, w_deck,
spacing, vert_orientation=vert, spacing, vert_orientation=vert,
deck_reveal=reveal_mode, flip=(i == 1 or i == 2), deck_reveal=reveal_mode, flip=(i == 1 or i == 2),
draw_from_last=(i == 2 or i == 3))) draw_from_last=(i == 2 or i == 3)))
self.players[i].connect_to_table(self.table_status) self.players[i].connect_to_table(self.table_status)
if i > 0: if i > 0:
self.players[i].add_ai(ai.RandomAI(self.table_status)) self.players[i].add_ai(ai.RandomAI(self.table_status))
@ -183,8 +191,6 @@ class Table:
self.ongoing = False self.ongoing = False
self.require_player_input = False self.require_player_input = False
def center_text_on_surface(self, surf, rendered_text, clear_colour): def center_text_on_surface(self, surf, rendered_text, clear_colour):
line_center = surf.get_rect().center line_center = surf.get_rect().center
text_rect = rendered_text.get_rect(center=line_center) text_rect = rendered_text.get_rect(center=line_center)
@ -274,7 +280,7 @@ class Table:
def get_pos(self): def get_pos(self):
return self.x, self.y return self.x, self.y
def continue_game(self): def continue_game(self, game_events):
""" """
This is where the FSM is. State transition should occur here. This is where the FSM is. State transition should occur here.
What takes place in the state should be in a function. What takes place in the state should be in a function.
@ -303,7 +309,7 @@ class Table:
self.update_team_scores() self.update_team_scores()
elif self.game_state == GameState.PLAYING: elif self.game_state == GameState.PLAYING:
self.play_a_round() self.play_a_round(game_events)
if self.current_round == 13: if self.current_round == 13:
self.write_message("Game Set! Press P to play again!") self.write_message("Game Set! Press P to play again!")
self.ongoing = False self.ongoing = False
@ -410,23 +416,54 @@ class Table:
self.write_message(msg, line=1, delay_time=1) self.write_message(msg, line=1, delay_time=1)
return True return True
def play_a_round(self): def play_a_round(self, game_events):
""" """
Ask each player to play a valid card and determine the winner of the round Ask each player to play a valid card and determine the winner of the round
This must work without pause if only bots are playing
The function will exit after every player decision or if a user input is needed.
If a user input is required, the function will continuously exit without proceeding to the next player
until a valid input is received.
:return: None :return: None
""" """
if not any(self.table_status["played cards"]): if not any(self.table_status["played cards"]):
# Leading player starts with the leading card, which determines the leading suit # Leading player starts with the leading card, which determines the leading suit
if not self.require_player_input:
self.current_player = self.table_status['leading player'] self.current_player = self.table_status['leading player']
self.display_current_player(self.current_player) self.display_current_player(self.current_player)
if not self.players[self.current_player].AI:
self.require_player_input = True
return
else:
card = self.players[self.current_player].make_decision(self.game_state, 0) card = self.players[self.current_player].make_decision(self.game_state, 0)
else:
card = self.players[self.current_player].make_decision(self.game_state, 0, game_events)
if not type(card) is cards.Card:
if card:
self.update_table.emit()
return
self.require_player_input = False
self.table_status["played cards"][self.current_player] = card self.table_status["played cards"][self.current_player] = card
self.players_playzone[self.current_player].add_card(card) self.players_playzone[self.current_player].add_card(card)
elif not all(self.table_status["played cards"]): elif not all(self.table_status["played cards"]):
# Subsequent player make their plays, following suit if possible # Subsequent player make their plays, following suit if possible
if not self.require_player_input:
self.display_current_player(self.current_player) self.display_current_player(self.current_player)
print("Player {0:d}\n".format(self.current_player)) if not self.players[self.current_player].AI:
self.require_player_input = True
return
else:
card = self.players[self.current_player].make_decision(self.game_state, 1) card = self.players[self.current_player].make_decision(self.game_state, 1)
else:
card = self.players[self.current_player].make_decision(self.game_state, 1, game_events)
if not type(card) is cards.Card:
if card:
self.update_table.emit()
return
self.require_player_input = False
self.players_playzone[self.current_player].add_card(card) self.players_playzone[self.current_player].add_card(card)
self.table_status["played cards"][self.current_player] = card self.table_status["played cards"][self.current_player] = card
else: else: