7 Replies - 471 Views - Last Post: 06 January 2018 - 08:36 AM

#1 cedpoker  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 4
  • Joined: 03-January 18

Poker web app

Posted 03 January 2018 - 01:50 PM

Hello, I'm in the design phase of a pet project of a poker web application.

I've made my first diagram today that is an OO representation of a game of poker. It's a very early draft and I left out everything network related to start with the simplest form.


(I don't know how to make diagrams so don't laugh please).

https://imgur.com/yPiY12E

I had lines between the entities but those were lost when exporting. A dealer as a Deck and has Players. A Player has a Hand and a Hand has Cards.

I'll start implementing this this evening (it's 22'o here, so now) and I'll post again tomorrow about it.

I'll be building the backend with node, and the front end with javascript but that really doesn't matter as the purpose of this post is to make an architectural blog from beginning to end of a project. I hope I'll be able to get some useful advises here and I'm very committed to reach the end of the project.

Cheers.

Posted Image

Is This A Good Question/Topic? 0
  • +

Replies To: Poker web app

#2 modi123_1  Icon User is offline

  • Suitor #2
  • member icon



Reputation: 14038
  • View blog
  • Posts: 56,176
  • Joined: 12-June 08

Re: Poker web app

Posted 03 January 2018 - 01:51 PM

You know there's a blog area up at top in the tool bar, right? ;)

Side question - why would a dealer have players? Wouldn't it make more sense if a 'table' had a 'dealer' and 'zero to many' players?
Was This Post Helpful? 2
  • +
  • -

#3 cedpoker  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 4
  • Joined: 03-January 18

Re: Poker web app

Posted 03 January 2018 - 04:17 PM

Actually no I didn't know there was a blog area.

I actually started with the name Table for that class then chose Dealer. I pondered having two classes but I felt like it didn't make semantic sens and might introduce some unnecessary indirection. This is because the Table would have Players, thus when the dealer would ask for bets it would ask the table for the Players. It seems odd to ask something to a table. But I might be victim of humanizing my classes (dunno if there is a name for that).

Well that was this morning but now I think you are right. Furthermore a Table could have settings (like 6max, 9max, etc.).

I did quite well this evening with the hour I had before sleep. I changed the schema by introducing Rank, and Suit enums. I implemented those plus Card and Hand. All in all I gotta say that it was more fun than I thought. I kinda forgot the fun one can have by doing his own pet projects.

I have also implemented
Hand.isFlush(), Hand.isStraight(), Hand.isStraightFlush(), Hand.isRoyalFlush(), Hand.isFourOfAKind()
. There is probably an algorithm out there that can calculate an int for hand strength but I didn't find one. So I chose the easy route to check for every combination, there aren't much after all.

The method
evaluateHand()
isn't finished yet as I'm not yet sure what it should return. Ultimately this method should be used to compare multiple hands and to pick a winner.

My roadmap



- By this sunday / next sunday I'd like to have a terminal working version where I can pick the number of players and play some hands against myself.
- The week after that I'd like to attack the networking part, I'll do this under websockets as I have my own lib that would work well with this. I hope to do so in a week as well.
- The week after I'll attack the UI (this one scares me a lil).
- The week after I'd like to attack multiple rooms with users accounts.

Kind of a tight roadmap and I probably won't finish in time but who knows, anyway I'll just have fun doing it.

I'll post some code tomorrow.

Cheers.
Was This Post Helpful? 0
  • +
  • -

#4 NeoTifa  Icon User is offline

  • NeoTifa Codebreaker, the Scourge of Devtester
  • member icon





Reputation: 4202
  • View blog
  • Posts: 18,438
  • Joined: 24-September 08

Re: Poker web app

Posted 04 January 2018 - 09:01 AM

Actually Modi's makes more sense. What if you opened it up to multiple players being a "dealer", as in you play as a standard player or a dealer? This is a separation of concerns thing that is basically what OOP embodies. There is probably not much more overhead involved in separating it. In fact, dealer can probably just extend player as a special case. Having a separate Game class would also be good. Each table can only have 1 game at a time, 1 dealer, and 0-however many players. You can put those constraints into place. The more it resembles real life, the better.
Was This Post Helpful? 0
  • +
  • -

#5 modi123_1  Icon User is offline

  • Suitor #2
  • member icon



Reputation: 14038
  • View blog
  • Posts: 56,176
  • Joined: 12-June 08

Re: Poker web app

Posted 04 January 2018 - 09:11 AM

... or cut out the middleman and punt on the idea of 'dealer' and the table is the 'dealer'... but I don't know what the overarching needs are so, it is just a thought.
Was This Post Helpful? 0
  • +
  • -

#6 jon.kiparsky  Icon User is offline

  • Beginner
  • member icon


Reputation: 11040
  • View blog
  • Posts: 18,852
  • Joined: 19-March 11

Re: Poker web app

Posted 04 January 2018 - 10:09 AM

There are easily half a dozen sensible ways to implement this - some of them have a "Dealer" class and some don't. You can't evaluate part of a design.

It's almost certainly pointless to write code at this point. What you need at this stage is requirements. I don't even know whether you're playing draw, stud, or both or neither. How are we going to talk sensibly about your design when we don't know what it is you want to do?
Was This Post Helpful? 1
  • +
  • -

#7 cedpoker  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 4
  • Joined: 03-January 18

Re: Poker web app

Posted 06 January 2018 - 08:27 AM

Sorry for being vague:

The utlimate goal is to make a hold'em poker web app where player can select a table of cash game and start playing with play money tied to his account.

I'll start with the big picture just to give an idea of the end goal, feel free to ask questions, then I'll give more detailed requirement of the stage I'm working on:

- A web client where User can select a Table in a list of Tables from the lobby.
- A table consist of 0 to 9 player. A table can be a head's up table meaning 2max players, could also be 6max or 9max. Those are standards.
- Game played is Hold'em poker.
- There are blinds, no antes.
- When a player has a decision to make he has a set amount of time before he automatically checks / fold depending on what's available.
- Visually speaking I'd like to have a dumbed down version of what other poker software out there display meaning we'd be able to see:

- The table, the current players, who has its turn (who is currently taking a decision), the pot size, etc.
- In other words, all the informations needed to play poker should be there.
- No statistics displayed
- I'd like to also log what happens on the bottom left, eg: Player1 raised for 1500.


That's for the end goal. However it's far away, so my first milestone is to make a terminal version where I can play against myself. I'd launch the program, select the number of players I want and start playing as a player myself.


I divided this milestone in 3 stages:

- Hand Evaluation: evaluating a Hand strength and compare it to another Hand. (where I am now, I'm not yet sure what the next step should be)
- Deck, table, dealer: A table of x players (hard coded) that join the table. Deck is randomized. 2 cards per player are given. The board display 3 flop, turn and river then picks the best hand. Next round the button is for the player on the left of the one that had it the previous round.
At this stage the players don't take action. When the flop arrives then the empty function askPlayerDecision() is called, then same for the turn and river.
- implement player decision with timebank.


So at the moment I'm at the hand evaluation phase: Evaluate hand strength & compare compare hand to another hand.

Key point:


- In Hold'em poker a hand strength is given by the best combination possible of the two cards the player is holding + the 5 cards on the table. That is true in all cases, even when the round is only at the flop stage, there are 2 cards to come, and the hand strength is only evaluated then.
- Permutations don't matter: Ad Jd 2d 8h 7c === 2d 7c Jd Ad 8h
- The different levels of strength are, from highest to lowest: ROYAL FLUSH, STRAIGHT FLUSH, FOUR OF A KIND, FULL HOUSE, FLUSH, STRAIGHT, SET( 3 of a kind), DOUBLE PAIR, PAIR, HIGH CARD.
- when two hands have the same strength additional factors needs to be checked. For example 2 players having a FOUR OF A KIND, must check who has the highest FOUR OF A KIND. EG: Ad Ah As Ac 8h > 9d 9h 9s 9c Kc
- Therefor there is at most 6 values that needs to be checked when picking a winner. That is in the case where two players have the HIGH CARD strength. EG: 6d 7h 9c Ts As < 5d 7h 9c Ts As. If the values are placed in an array that would be: [HIGH_CARD, A, T, 9, 7, 6] vs [HIGH_CARD, A, T, 9, 7, 5] and we would be able to pick a winner at 5. Another solution would be to generate an integer to compare the two.


Simple API & good design choices

Since this will be at the core of the application I'd like to have to take good design choices instead of rushing through the implementation.

For the simple api one choice I made that I'm happy about is to have toString and fromString methods for Card & Hand. That has proven to be great for testing. I think the test below is readable even if you don't know javascript / jasmine testing framework.

   expect(hv.evaluateHand(Hand.fromString('2s 4h 4s 7s 8s 9s 9d')).rank).toBe(HandRank.FLUSH);



Having said that, I think it's hard to fully understand the scope of a task without implementing a bit. So I started already. And I'm not happy with the result.

Here is my current design:

Posted Image

The orange square are for enums, the green ones are classes I already implemented, and the white ones are not implemented nor are they part of the current objective, but I felt like putting those in as to keep in mind the future scope.

The big hurdle when implementing was this:

- In real life a player hand is the two cards he/she is holding. However in my design a player hand is the hand he is holding + the cards on the board. I don't think that makes much sens. However it made some things easy :

// the Hand class contains the player cards + board cards.
export class Hand {
	public cards: Card[] = [];
	// those two are used when evaluating a hand
	// take a look at evaluate hand for more details
	public suits: Card[][] = new Array(4).fill(0).map(_ => []);
	public ranks: Card[][] = new Array(13).fill(0).map(_ => []);

	addCard(card: Card): Hand {
                // there is error handling here

		this.cards.push(card);
		// we are adding the suit and ranks to their respective array so we can easily
		// evaluate those.
		this.suits[card.suit].push(card);
		this.ranks[card.rank].push(card);
		return this;
	}





Having this sort of code makes it easy to spot if a player holds a PAIR. We just have to check if any array in the ranks matrix has a length of 2.
Same for flushes, we need to check if one of the array in suits has a length of at least 5.


However I'm not sure that mimicks the real world. So I'm not really happy about that.

What I'm the least happy about is me introducing WinningHand though. See, the HandEvaluator class has a method evaluateHand(hand). That method evaluate the best possible combination of 7 cards and gives it back with it's HandRank (FULL_HOUSE, PAIR, etc). Thus I introduced the WinningHand class to represent that. Not happy about that tbh.

The most interesting part is the HandEvaluator. Which was pretty fun to code. But I'll post the implementation when I've found a design I'm happy with.

Any help / feedback is appreciated.

Cheers.
Was This Post Helpful? 0
  • +
  • -

#8 cedpoker  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 4
  • Joined: 03-January 18

Re: Poker web app

Posted 06 January 2018 - 08:36 AM

*There are two typos in the post above :

1
  • in the diagram it should be rank: Rank enum; suit: Suit: enum
  • in the high pair comparison it should be > instead of <



I don't know yet how to edit my post.
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1