Integrate panel to bidding
parent
016a39a466
commit
f88b0abda3
89
UI.py
89
UI.py
|
@ -5,6 +5,8 @@ from signalslot import Signal
|
|||
|
||||
class GenericUI:
|
||||
def __init__(self, x, y, width, height):
|
||||
self.draw_update = Signal()
|
||||
|
||||
self.x = x
|
||||
self.y = y
|
||||
self.width = width
|
||||
|
@ -82,13 +84,13 @@ class TextBox(GenericUI):
|
|||
|
||||
def redraw(self):
|
||||
super().redraw()
|
||||
if self.visible:
|
||||
outline = (0, 0, self.rect.w, self.rect.h)
|
||||
pygame.draw.rect(self.background, self.outline_colour, outline, self.outline_thickness)
|
||||
rendered_text = self.font.render(self.text, True, self.text_colour).convert_alpha()
|
||||
rect_center = self.background.get_rect().center
|
||||
text_rect = rendered_text.get_rect(center=rect_center)
|
||||
self.background.blit(rendered_text, text_rect)
|
||||
#if self.visible:
|
||||
outline = (0, 0, self.rect.w, self.rect.h)
|
||||
pygame.draw.rect(self.background, self.outline_colour, outline, self.outline_thickness)
|
||||
rendered_text = self.font.render(self.text, True, self.text_colour).convert_alpha()
|
||||
rect_center = self.background.get_rect().center
|
||||
text_rect = rendered_text.get_rect(center=rect_center)
|
||||
self.background.blit(rendered_text, text_rect)
|
||||
|
||||
def set_text(self, text):
|
||||
self.text = text
|
||||
|
@ -112,13 +114,13 @@ class Button(TextBox):
|
|||
self.background.fill((255, 255, 255))
|
||||
else:
|
||||
super().redraw()
|
||||
if self.visible:
|
||||
outline = (0, 0, self.rect.w, self.rect.h)
|
||||
pygame.draw.rect(self.background, self.outline_colour, outline, self.outline_thickness)
|
||||
rendered_text = self.font.render(self.text, True, self.text_colour).convert_alpha()
|
||||
rect_center = self.background.get_rect().center
|
||||
text_rect = rendered_text.get_rect(center=rect_center)
|
||||
self.background.blit(rendered_text, text_rect)
|
||||
#if self.visible:
|
||||
outline = (0, 0, self.rect.w, self.rect.h)
|
||||
pygame.draw.rect(self.background, self.outline_colour, outline, self.outline_thickness)
|
||||
rendered_text = self.font.render(self.text, True, self.text_colour).convert_alpha()
|
||||
rect_center = self.background.get_rect().center
|
||||
text_rect = rendered_text.get_rect(center=rect_center)
|
||||
self.background.blit(rendered_text, text_rect)
|
||||
|
||||
def hold(self, *args):
|
||||
if not self.button_down:
|
||||
|
@ -164,17 +166,17 @@ class ScrollList(GenericUI):
|
|||
|
||||
def redraw(self):
|
||||
super().redraw()
|
||||
if self.visible:
|
||||
outline = (0, 0, self.rect.w, self.rect.h)
|
||||
pygame.draw.rect(self.background, self.outline_colour, outline, self.outline_thickness)
|
||||
i = 0
|
||||
for text, text_rect in zip(self.texts, self.text_rects):
|
||||
if i == self.selected:
|
||||
pygame.draw.rect(self.background, self.selected_colour, text_rect)
|
||||
rendered_text = self.font.render(text, True, self.text_colour).convert_alpha()
|
||||
#if self.visible:
|
||||
outline = (0, 0, self.rect.w, self.rect.h)
|
||||
pygame.draw.rect(self.background, self.outline_colour, outline, self.outline_thickness)
|
||||
i = 0
|
||||
for text, text_rect in zip(self.texts, self.text_rects):
|
||||
if i == self.selected:
|
||||
pygame.draw.rect(self.background, self.selected_colour, text_rect)
|
||||
rendered_text = self.font.render(text, True, self.text_colour).convert_alpha()
|
||||
|
||||
self.background.blit(rendered_text, text_rect)
|
||||
i += 1
|
||||
self.background.blit(rendered_text, text_rect)
|
||||
i += 1
|
||||
|
||||
def process_events(self, event):
|
||||
draw_update = super().process_events(event)
|
||||
|
@ -274,6 +276,7 @@ class ScrollList(GenericUI):
|
|||
current_y += text_rect.height
|
||||
self.max_offset = max(0, current_y - self.height - self.outline_thickness)
|
||||
self.redraw()
|
||||
self.draw_update.emit()
|
||||
|
||||
|
||||
class CallPanel(GenericUI):
|
||||
|
@ -291,7 +294,7 @@ class CallPanel(GenericUI):
|
|||
ui_width = 75
|
||||
ui_height = 25
|
||||
width_spacings = (width - 3 * ui_width - 2 * margins) / 4
|
||||
height_spacings = (height - 2 * margins - 2 * ui_height) / 3
|
||||
height_spacings = (height - 2 * margins - 3 * ui_height) / 4
|
||||
self.output_text = ['', '']
|
||||
|
||||
self.label1 = TextBox(margins+width_spacings, margins,
|
||||
|
@ -309,33 +312,39 @@ class CallPanel(GenericUI):
|
|||
self.list2.list_selected.connect(lambda text, **z: self.print_list_selection(text, 1))
|
||||
|
||||
self.output_box = TextBox(margins+width_spacings*3+ui_width*2, margins+height_spacings,
|
||||
ui_width, ui_height, text_size=self.text_size)
|
||||
ui_width, ui_height, text='Bid', text_size=self.text_size)
|
||||
|
||||
self.confirm_button = Button(margins+width_spacings*3+ui_width*2, margins+height_spacings*2+ui_height,
|
||||
ui_width, ui_height, text='OK', text_size=self.text_size)
|
||||
self.confirm_button.clicked.connect(self.emit_output)
|
||||
self.cancel_button = Button(margins + width_spacings * 3 + ui_width * 2,
|
||||
margins + height_spacings * 3 + ui_height * 2,
|
||||
ui_width, ui_height, text='Cancel', text_size=self.text_size)
|
||||
|
||||
self.cancel_button.visible = False
|
||||
self.cancel_button.clicked.connect(self.cancelling)
|
||||
self.children = [self.label1, self.list1, self.label2, self.list2,
|
||||
self.confirm_button, self.output_box]
|
||||
self.confirm_button, self.output_box, self.cancel_button]
|
||||
for element in self.children:
|
||||
element.parent = self
|
||||
|
||||
self.redraw()
|
||||
|
||||
def redraw(self):
|
||||
def redraw(self, **kwargs):
|
||||
super().redraw()
|
||||
#self.background.fill((255,0,255))
|
||||
if self.visible:
|
||||
outline = (0, 0, self.rect.w, self.rect.h)
|
||||
pygame.draw.rect(self.background, self.outline_colour, outline, self.outline_thickness)
|
||||
#if self.visible:
|
||||
outline = (0, 0, self.rect.w, self.rect.h)
|
||||
pygame.draw.rect(self.background, self.outline_colour, outline, self.outline_thickness)
|
||||
|
||||
for element in self.children:
|
||||
for element in self.children:
|
||||
if element.visible:
|
||||
self.background.blit(element.background, element.get_pos())
|
||||
|
||||
def process_events(self, event):
|
||||
draw_update = False
|
||||
for element in self.children:
|
||||
if element.process_events(event):
|
||||
if element.visible and element.process_events(event):
|
||||
draw_update = True
|
||||
|
||||
if draw_update:
|
||||
|
@ -347,9 +356,17 @@ class CallPanel(GenericUI):
|
|||
self.output_box.set_text(' '.join(self.output_text))
|
||||
|
||||
def emit_output(self, **kwargs):
|
||||
output = self.output_text[0]+self.output_text[1][0].lower()
|
||||
initial = ''
|
||||
if self.output_text[1]:
|
||||
initial = self.output_text[1][0].lower()
|
||||
|
||||
output = self.output_text[0].lower() + initial
|
||||
self.confirm_output.emit(output=output)
|
||||
|
||||
def cancelling(self, **kwargs):
|
||||
self.confirm_output.emit(output='')
|
||||
|
||||
|
||||
class TestScreen(view.PygView):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
|
@ -393,6 +410,10 @@ class TestScreen(view.PygView):
|
|||
if event.key == pygame.K_ESCAPE:
|
||||
running = False
|
||||
|
||||
if event.key == pygame.K_o:
|
||||
self.panel.list1.replace_list([str(i+1) for i in range(7)])
|
||||
draw_update = True
|
||||
|
||||
for element in self.elements:
|
||||
if element.process_events(event):
|
||||
draw_update = True
|
||||
|
|
|
@ -21,3 +21,4 @@ HIGHEST_CARD = 414
|
|||
LOWEST_CARD = 102
|
||||
DOUBLE_CLICK_EVENT = pygame.USEREVENT + 1
|
||||
DOUBLE_CLICK_TIMING = 300
|
||||
CALL_EVENT = pygame.USEREVENT + 2
|
||||
|
|
36
players.py
36
players.py
|
@ -1,7 +1,7 @@
|
|||
import cards
|
||||
import pprint
|
||||
import pygame
|
||||
from game_consts import GameState, PlayerRole, STARTING_HAND, DOUBLE_CLICK_EVENT, DOUBLE_CLICK_TIMING
|
||||
from game_consts import GameState, PlayerRole, STARTING_HAND, DOUBLE_CLICK_EVENT, DOUBLE_CLICK_TIMING, CALL_EVENT
|
||||
|
||||
|
||||
class Player(cards.Deck):
|
||||
|
@ -57,7 +57,7 @@ class Player(cards.Deck):
|
|||
if sub_state == 0:
|
||||
if self.AI:
|
||||
return self.AI.make_a_bid()
|
||||
return self.make_a_bid()
|
||||
return self.make_a_bid(game_events=game_events)
|
||||
else:
|
||||
if self.AI:
|
||||
return self.AI.call_partner()
|
||||
|
@ -69,7 +69,7 @@ class Player(cards.Deck):
|
|||
return self.remove_card(pos)
|
||||
return self.make_a_play(sub_state, game_events=game_events)
|
||||
|
||||
def make_a_bid(self):
|
||||
def make_a_bid(self, game_events=None):
|
||||
"""
|
||||
The procedure to make a bid
|
||||
:return: A valid bid number
|
||||
|
@ -191,6 +191,36 @@ class MainPlayer(Player):
|
|||
self.left_mouse_down = False
|
||||
self.double_clicking = False
|
||||
|
||||
def make_a_bid(self, game_events=None):
|
||||
"""
|
||||
The procedure to make a bid
|
||||
:return: A valid bid number
|
||||
"""
|
||||
if game_events:
|
||||
for event in game_events:
|
||||
if event.type == CALL_EVENT:
|
||||
bid = event.call
|
||||
print(bid)
|
||||
|
||||
if not bid:
|
||||
return 0
|
||||
|
||||
bid = cards.convert_bid_string(bid)
|
||||
if bid < 0:
|
||||
print("Error in processing bid")
|
||||
return -1
|
||||
|
||||
if self._table_status["bid"] >= bid:
|
||||
if bid > 75:
|
||||
print("You cannot bid beyond 7 No Trump")
|
||||
else:
|
||||
print("You might need to bid higher")
|
||||
return -1
|
||||
return bid
|
||||
return -1
|
||||
return -1
|
||||
|
||||
|
||||
def make_a_play(self, substate, game_events=None):
|
||||
card = None
|
||||
if game_events:
|
||||
|
|
52
table.py
52
table.py
|
@ -8,7 +8,7 @@ import copy
|
|||
import time
|
||||
from signalslot import Signal
|
||||
from ai_comp import ai
|
||||
from game_consts import GameState, PlayerRole, STARTING_HAND, NUM_OF_PLAYERS
|
||||
from game_consts import GameState, PlayerRole, STARTING_HAND, NUM_OF_PLAYERS, CALL_EVENT
|
||||
|
||||
VIEW_TRANSPARENT = False # Make the text box not transparent
|
||||
|
||||
|
@ -49,10 +49,10 @@ class Table:
|
|||
All played cards go into a hidden discard pile.
|
||||
|
||||
"""
|
||||
update_table = Signal()
|
||||
|
||||
def __init__(self, x, y, width, height, clear_colour, autoplay=False, view_all_cards=False):
|
||||
# TODO: Reduce the amount of update_table call
|
||||
self.update_table = Signal()
|
||||
self.x = x
|
||||
self.y = y
|
||||
self.width = width
|
||||
|
@ -195,8 +195,15 @@ class Table:
|
|||
self.calling_panel = UI.CallPanel(playdeckx[0]+w_deck+5,playdecky[0]+w_deck-140,
|
||||
250, 140)
|
||||
self.calling_panel.parent = self
|
||||
self.calling_panel.visible = False
|
||||
self.parent = None
|
||||
|
||||
self.calling_panel.confirm_output.connect(self.emit_call)
|
||||
|
||||
def emit_call(self, output, **kwargs):
|
||||
print(output)
|
||||
pygame.event.post(pygame.event.Event(CALL_EVENT, call=output))
|
||||
|
||||
def get_offset_pos(self):
|
||||
x, y = 0, 0
|
||||
if self.parent:
|
||||
|
@ -306,7 +313,6 @@ class Table:
|
|||
if draw_update:
|
||||
self.update_table.emit()
|
||||
|
||||
|
||||
def continue_game(self, game_events):
|
||||
"""
|
||||
This is where the FSM is. State transition should occur here.
|
||||
|
@ -329,7 +335,7 @@ class Table:
|
|||
self.write_message("Start to Bid")
|
||||
self.prepare_bidding()
|
||||
elif self.game_state == GameState.BIDDING:
|
||||
bid_complete = self.start_bidding()
|
||||
bid_complete = self.start_bidding(game_events)
|
||||
if bid_complete:
|
||||
self.game_state = GameState.PLAYING
|
||||
self.update_all_players(role=True, wins=True)
|
||||
|
@ -385,30 +391,52 @@ class Table:
|
|||
1 * (not self.first_player)) % NUM_OF_PLAYERS)
|
||||
self.write_message(msg, line=2, delay_time=1)
|
||||
|
||||
def start_bidding(self):
|
||||
self.calling_panel.list1.replace_list([str(i+1) for i in range(7)])
|
||||
self.calling_panel.list2.replace_list(['Clubs', 'Diamonds', 'Hearts', 'Spades', 'No Trump'])
|
||||
self.calling_panel.cancel_button.visible = True
|
||||
self.calling_panel.redraw()
|
||||
|
||||
self.update_table.emit()
|
||||
|
||||
def start_bidding(self, game_events):
|
||||
"""
|
||||
The bidding procedure.
|
||||
:return: Whether bidding is completed
|
||||
"""
|
||||
# Highest bid: 7 NoTrump. No further check required
|
||||
if self.passes < NUM_OF_PLAYERS - 1 and self.table_status["bid"] < 75:
|
||||
player_bid = self.players[self.current_player].make_decision(self.game_state, 0)
|
||||
if not self.require_player_input:
|
||||
if not self.players[self.current_player].AI:
|
||||
self.require_player_input = True
|
||||
self.calling_panel.visible = True
|
||||
self.update_table.emit()
|
||||
return
|
||||
else:
|
||||
player_bid = self.players[self.current_player].make_decision(self.game_state, 0)
|
||||
else:
|
||||
player_bid = self.players[self.current_player].make_decision(self.game_state, 0, game_events)
|
||||
|
||||
if player_bid < 0:
|
||||
return
|
||||
self.require_player_input = False
|
||||
self.calling_panel.visible = False
|
||||
self.update_table.emit()
|
||||
|
||||
if not player_bid:
|
||||
if not self.first_player: # Starting bidder pass do not count at the start
|
||||
self.passes += 1
|
||||
else:
|
||||
self.table_status["bid"] = player_bid
|
||||
self.passes = 0
|
||||
msg = "Current Bid: {0:d} {1:s}".format(self.table_status["bid"] // 10,
|
||||
cards.get_suit_string(self.table_status["bid"] % 10))
|
||||
self.write_message(msg, line=1, update_now=False)
|
||||
msg = 'Bid Leader: Player {0:d}'.format(self.current_player)
|
||||
self.write_message(msg, line=2, update_now=True)
|
||||
|
||||
if self.table_status["bid"] < 75:
|
||||
self.current_player += 1
|
||||
self.current_player %= NUM_OF_PLAYERS
|
||||
msg = "Current Bid: {0:d} {1:s}".format(self.table_status["bid"] // 10,
|
||||
cards.get_suit_string(self.table_status["bid"] % 10))
|
||||
self.write_message(msg, line=1, update_now=False)
|
||||
msg = 'Bid Leader: Player {0:d}'.format((self.current_player - self.passes
|
||||
- 1 * (not self.first_player)) % NUM_OF_PLAYERS)
|
||||
self.write_message(msg, line=2, update_now=False)
|
||||
self.display_current_player(self.current_player)
|
||||
if self.first_player:
|
||||
self.first_player = False
|
||||
|
|
Loading…
Reference in New Issue