Integrate panel to bidding
parent
016a39a466
commit
f88b0abda3
41
UI.py
41
UI.py
|
@ -5,6 +5,8 @@ from signalslot import Signal
|
||||||
|
|
||||||
class GenericUI:
|
class GenericUI:
|
||||||
def __init__(self, x, y, width, height):
|
def __init__(self, x, y, width, height):
|
||||||
|
self.draw_update = Signal()
|
||||||
|
|
||||||
self.x = x
|
self.x = x
|
||||||
self.y = y
|
self.y = y
|
||||||
self.width = width
|
self.width = width
|
||||||
|
@ -82,7 +84,7 @@ class TextBox(GenericUI):
|
||||||
|
|
||||||
def redraw(self):
|
def redraw(self):
|
||||||
super().redraw()
|
super().redraw()
|
||||||
if self.visible:
|
#if self.visible:
|
||||||
outline = (0, 0, self.rect.w, self.rect.h)
|
outline = (0, 0, self.rect.w, self.rect.h)
|
||||||
pygame.draw.rect(self.background, self.outline_colour, outline, self.outline_thickness)
|
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()
|
rendered_text = self.font.render(self.text, True, self.text_colour).convert_alpha()
|
||||||
|
@ -112,7 +114,7 @@ class Button(TextBox):
|
||||||
self.background.fill((255, 255, 255))
|
self.background.fill((255, 255, 255))
|
||||||
else:
|
else:
|
||||||
super().redraw()
|
super().redraw()
|
||||||
if self.visible:
|
#if self.visible:
|
||||||
outline = (0, 0, self.rect.w, self.rect.h)
|
outline = (0, 0, self.rect.w, self.rect.h)
|
||||||
pygame.draw.rect(self.background, self.outline_colour, outline, self.outline_thickness)
|
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()
|
rendered_text = self.font.render(self.text, True, self.text_colour).convert_alpha()
|
||||||
|
@ -164,7 +166,7 @@ class ScrollList(GenericUI):
|
||||||
|
|
||||||
def redraw(self):
|
def redraw(self):
|
||||||
super().redraw()
|
super().redraw()
|
||||||
if self.visible:
|
#if self.visible:
|
||||||
outline = (0, 0, self.rect.w, self.rect.h)
|
outline = (0, 0, self.rect.w, self.rect.h)
|
||||||
pygame.draw.rect(self.background, self.outline_colour, outline, self.outline_thickness)
|
pygame.draw.rect(self.background, self.outline_colour, outline, self.outline_thickness)
|
||||||
i = 0
|
i = 0
|
||||||
|
@ -274,6 +276,7 @@ class ScrollList(GenericUI):
|
||||||
current_y += text_rect.height
|
current_y += text_rect.height
|
||||||
self.max_offset = max(0, current_y - self.height - self.outline_thickness)
|
self.max_offset = max(0, current_y - self.height - self.outline_thickness)
|
||||||
self.redraw()
|
self.redraw()
|
||||||
|
self.draw_update.emit()
|
||||||
|
|
||||||
|
|
||||||
class CallPanel(GenericUI):
|
class CallPanel(GenericUI):
|
||||||
|
@ -291,7 +294,7 @@ class CallPanel(GenericUI):
|
||||||
ui_width = 75
|
ui_width = 75
|
||||||
ui_height = 25
|
ui_height = 25
|
||||||
width_spacings = (width - 3 * ui_width - 2 * margins) / 4
|
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.output_text = ['', '']
|
||||||
|
|
||||||
self.label1 = TextBox(margins+width_spacings, margins,
|
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.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,
|
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,
|
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)
|
ui_width, ui_height, text='OK', text_size=self.text_size)
|
||||||
self.confirm_button.clicked.connect(self.emit_output)
|
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.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:
|
for element in self.children:
|
||||||
element.parent = self
|
element.parent = self
|
||||||
|
|
||||||
self.redraw()
|
self.redraw()
|
||||||
|
|
||||||
def redraw(self):
|
def redraw(self, **kwargs):
|
||||||
super().redraw()
|
super().redraw()
|
||||||
#self.background.fill((255,0,255))
|
#self.background.fill((255,0,255))
|
||||||
if self.visible:
|
#if self.visible:
|
||||||
outline = (0, 0, self.rect.w, self.rect.h)
|
outline = (0, 0, self.rect.w, self.rect.h)
|
||||||
pygame.draw.rect(self.background, self.outline_colour, outline, self.outline_thickness)
|
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())
|
self.background.blit(element.background, element.get_pos())
|
||||||
|
|
||||||
def process_events(self, event):
|
def process_events(self, event):
|
||||||
draw_update = False
|
draw_update = False
|
||||||
for element in self.children:
|
for element in self.children:
|
||||||
if element.process_events(event):
|
if element.visible and element.process_events(event):
|
||||||
draw_update = True
|
draw_update = True
|
||||||
|
|
||||||
if draw_update:
|
if draw_update:
|
||||||
|
@ -347,9 +356,17 @@ class CallPanel(GenericUI):
|
||||||
self.output_box.set_text(' '.join(self.output_text))
|
self.output_box.set_text(' '.join(self.output_text))
|
||||||
|
|
||||||
def emit_output(self, **kwargs):
|
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)
|
self.confirm_output.emit(output=output)
|
||||||
|
|
||||||
|
def cancelling(self, **kwargs):
|
||||||
|
self.confirm_output.emit(output='')
|
||||||
|
|
||||||
|
|
||||||
class TestScreen(view.PygView):
|
class TestScreen(view.PygView):
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
|
@ -393,6 +410,10 @@ class TestScreen(view.PygView):
|
||||||
if event.key == pygame.K_ESCAPE:
|
if event.key == pygame.K_ESCAPE:
|
||||||
running = False
|
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:
|
for element in self.elements:
|
||||||
if element.process_events(event):
|
if element.process_events(event):
|
||||||
draw_update = True
|
draw_update = True
|
||||||
|
|
|
@ -21,3 +21,4 @@ HIGHEST_CARD = 414
|
||||||
LOWEST_CARD = 102
|
LOWEST_CARD = 102
|
||||||
DOUBLE_CLICK_EVENT = pygame.USEREVENT + 1
|
DOUBLE_CLICK_EVENT = pygame.USEREVENT + 1
|
||||||
DOUBLE_CLICK_TIMING = 300
|
DOUBLE_CLICK_TIMING = 300
|
||||||
|
CALL_EVENT = pygame.USEREVENT + 2
|
||||||
|
|
36
players.py
36
players.py
|
@ -1,7 +1,7 @@
|
||||||
import cards
|
import cards
|
||||||
import pprint
|
import pprint
|
||||||
import pygame
|
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):
|
class Player(cards.Deck):
|
||||||
|
@ -57,7 +57,7 @@ class Player(cards.Deck):
|
||||||
if sub_state == 0:
|
if sub_state == 0:
|
||||||
if self.AI:
|
if self.AI:
|
||||||
return self.AI.make_a_bid()
|
return self.AI.make_a_bid()
|
||||||
return self.make_a_bid()
|
return self.make_a_bid(game_events=game_events)
|
||||||
else:
|
else:
|
||||||
if self.AI:
|
if self.AI:
|
||||||
return self.AI.call_partner()
|
return self.AI.call_partner()
|
||||||
|
@ -69,7 +69,7 @@ class Player(cards.Deck):
|
||||||
return self.remove_card(pos)
|
return self.remove_card(pos)
|
||||||
return self.make_a_play(sub_state, game_events=game_events)
|
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
|
The procedure to make a bid
|
||||||
:return: A valid bid number
|
:return: A valid bid number
|
||||||
|
@ -191,6 +191,36 @@ class MainPlayer(Player):
|
||||||
self.left_mouse_down = False
|
self.left_mouse_down = False
|
||||||
self.double_clicking = 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):
|
def make_a_play(self, substate, game_events=None):
|
||||||
card = None
|
card = None
|
||||||
if game_events:
|
if game_events:
|
||||||
|
|
50
table.py
50
table.py
|
@ -8,7 +8,7 @@ import copy
|
||||||
import time
|
import time
|
||||||
from signalslot import Signal
|
from signalslot import Signal
|
||||||
from ai_comp import ai
|
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
|
VIEW_TRANSPARENT = False # Make the text box not transparent
|
||||||
|
|
||||||
|
@ -49,10 +49,10 @@ class Table:
|
||||||
All played cards go into a hidden discard pile.
|
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):
|
def __init__(self, x, y, width, height, clear_colour, autoplay=False, view_all_cards=False):
|
||||||
# TODO: Reduce the amount of update_table call
|
# TODO: Reduce the amount of update_table call
|
||||||
|
self.update_table = Signal()
|
||||||
self.x = x
|
self.x = x
|
||||||
self.y = y
|
self.y = y
|
||||||
self.width = width
|
self.width = width
|
||||||
|
@ -195,8 +195,15 @@ class Table:
|
||||||
self.calling_panel = UI.CallPanel(playdeckx[0]+w_deck+5,playdecky[0]+w_deck-140,
|
self.calling_panel = UI.CallPanel(playdeckx[0]+w_deck+5,playdecky[0]+w_deck-140,
|
||||||
250, 140)
|
250, 140)
|
||||||
self.calling_panel.parent = self
|
self.calling_panel.parent = self
|
||||||
|
self.calling_panel.visible = False
|
||||||
self.parent = None
|
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):
|
def get_offset_pos(self):
|
||||||
x, y = 0, 0
|
x, y = 0, 0
|
||||||
if self.parent:
|
if self.parent:
|
||||||
|
@ -306,7 +313,6 @@ class Table:
|
||||||
if draw_update:
|
if draw_update:
|
||||||
self.update_table.emit()
|
self.update_table.emit()
|
||||||
|
|
||||||
|
|
||||||
def continue_game(self, game_events):
|
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.
|
||||||
|
@ -329,7 +335,7 @@ class Table:
|
||||||
self.write_message("Start to Bid")
|
self.write_message("Start to Bid")
|
||||||
self.prepare_bidding()
|
self.prepare_bidding()
|
||||||
elif self.game_state == GameState.BIDDING:
|
elif self.game_state == GameState.BIDDING:
|
||||||
bid_complete = self.start_bidding()
|
bid_complete = self.start_bidding(game_events)
|
||||||
if bid_complete:
|
if bid_complete:
|
||||||
self.game_state = GameState.PLAYING
|
self.game_state = GameState.PLAYING
|
||||||
self.update_all_players(role=True, wins=True)
|
self.update_all_players(role=True, wins=True)
|
||||||
|
@ -385,30 +391,52 @@ class Table:
|
||||||
1 * (not self.first_player)) % NUM_OF_PLAYERS)
|
1 * (not self.first_player)) % NUM_OF_PLAYERS)
|
||||||
self.write_message(msg, line=2, delay_time=1)
|
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.
|
The bidding procedure.
|
||||||
:return: Whether bidding is completed
|
:return: Whether bidding is completed
|
||||||
"""
|
"""
|
||||||
# Highest bid: 7 NoTrump. No further check required
|
# Highest bid: 7 NoTrump. No further check required
|
||||||
if self.passes < NUM_OF_PLAYERS - 1 and self.table_status["bid"] < 75:
|
if self.passes < NUM_OF_PLAYERS - 1 and self.table_status["bid"] < 75:
|
||||||
|
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)
|
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 player_bid:
|
||||||
if not self.first_player: # Starting bidder pass do not count at the start
|
if not self.first_player: # Starting bidder pass do not count at the start
|
||||||
self.passes += 1
|
self.passes += 1
|
||||||
else:
|
else:
|
||||||
self.table_status["bid"] = player_bid
|
self.table_status["bid"] = player_bid
|
||||||
self.passes = 0
|
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:
|
if self.table_status["bid"] < 75:
|
||||||
self.current_player += 1
|
self.current_player += 1
|
||||||
self.current_player %= NUM_OF_PLAYERS
|
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)
|
self.display_current_player(self.current_player)
|
||||||
if self.first_player:
|
if self.first_player:
|
||||||
self.first_player = False
|
self.first_player = False
|
||||||
|
|
Loading…
Reference in New Issue