Go Fish โ Design Document (Pseudocode)
Overview
The game is split into four logical modules: Card, Player, Game, and Main. Each module owns a clear slice of responsibility. The design supports 2โ6 players (human and/or AI) in a CLI environment.
Module: Card
Owns the raw building blocks โ suits, ranks, individual cards, the deck, and a player's hand.
Enum: Suit
1Suit = { Spades, Hearts, Diamonds, Clubs }
Enum: Rank
1Rank = { Ace, Two, Three, Four, Five, Six, Seven,
2 Eight, Nine, Ten, Jack, Queen, King }
Object: Card
1Card
2 properties:
3 rank : Rank
4 suit : Suit
5
6 methods:
7 toString() โ "Ace of Spades"
8 toShortString() โ "Aโ "
Object: Deck
1Deck
2 properties:
3 cards : list of Card
4
5 methods:
6 create()
7 -- build one Card for every (Rank, Suit) combination โ 52 cards total
8
9 shuffle()
10 -- randomize card order in place
11
12 deal(n) โ list of Card
13 -- remove and return the top n cards
14 -- error if fewer than n cards remain
15
16 drawOne() โ Card or null
17 -- remove and return the top card
18 -- return null if deck is empty
19
20 size() โ number
21 isEmpty() โ boolean
Object: Hand
1Hand
2 properties:
3 cards : list of Card
4
5 methods:
6 add(cards)
7 -- append one or more cards to the hand
8
9 hasRank(rank) โ boolean
10 -- return true if at least one card of this rank exists
11
12 takeByRank(rank) โ list of Card
13 -- remove and return all cards matching rank
14
15 collectBooks() โ list of Rank
16 -- find every rank that appears exactly 4 times
17 -- remove those cards from the hand
18 -- return the list of completed ranks
19
20 size() โ number
21 isEmpty() โ boolean
22 toString() โ human-readable card list
Module: Player
Manages player identity, their hand, their completed books, and AI decision-making.
Object: Player
1Player
2 properties:
3 id : number
4 name : string
5 hand : Hand
6 books : list of Rank -- completed four-of-a-kind sets
7 isHuman : boolean
8
9 methods:
10 bookCount() โ number
11 -- return length of books list
12
13 recordBook(rank)
14 -- append rank to books
15
16 score() โ number
17 -- same as bookCount, used at end of game
18
19 -- AI only --
20
21 chooseRank() โ Rank
22 -- pick the rank in hand with the most copies
23 -- (ties broken randomly)
24
25 chooseTarget(otherPlayers) โ Player
26 -- pick a random opponent who still has cards
Module: Game
The rules engine. Controls turn flow, enforces Go Fish rules, and tracks overall game state.
Enum: Phase
1Phase = { Ask, GoFish, GameOver }
Object: TurnResult
1TurnResult
2 properties:
3 asker : Player
4 target : Player
5 rankAsked : Rank
6 cardsReceived : list of Card -- cards transferred from target โ asker
7 wentFishing : boolean -- true if target had no matching cards
8 drawnCard : Card or null -- card drawn when fishing (null if deck empty)
9 booksScored : list of Rank -- any books completed this turn
10 turnEnds : boolean -- false means asker gets to go again
Object: Game
1Game
2 properties:
3 players : list of Player
4 deck : Deck
5 currentIndex : number -- index of the active player
6 phase : Phase
7 history : list of TurnResult
8
9 methods:
10 create(playerNames, humanFlags)
11 -- validate 2โ6 players
12 -- build Player objects
13 -- create and shuffle the Deck
14
15 start()
16 -- deal 7 cards each for 2 players, 5 cards each for 3โ6 players
17 -- collect any opening books from starting hands
18 -- set phase = Ask
19
20 currentPlayer() โ Player
21 -- return players[currentIndex]
22
23 ask(targetIndex, rank) โ TurnResult
24 -- validate phase is Ask
25 -- validate targetIndex is a different, eligible player
26 -- validate rank exists in asker's hand
27
28 -- if target has rank:
29 cards = target.hand.takeByRank(rank)
30 asker.hand.add(cards)
31 books = asker.hand.collectBooks()
32 record any new books on asker
33 set turnEnds = false (asker goes again)
34
35 -- if target does not have rank:
36 set phase = GoFish
37 set wentFishing = true
38 set turnEnds = true
39
40 -- build and store TurnResult
41 -- if turnEnds: call advanceTurn()
42 -- return TurnResult
43
44 goFish() โ TurnResult
45 -- validate phase is GoFish
46 -- draw one card from deck
47 -- add card to asker's hand
48 -- check for new book
49 -- set phase = Ask
50 -- advanceTurn()
51 -- return TurnResult
52
53 advanceTurn()
54 -- move currentIndex to the next player who still has cards
55 -- if no eligible players remain: set phase = GameOver
56
57 isOver() โ boolean
58 -- return true when deck is empty AND all hands are empty
59
60 winners() โ list of Player
61 -- return the player(s) with the highest book count
62
63 scores() โ map of name โ bookCount
64
65 eligiblePlayers() โ list of Player
66 -- return players who still have cards in hand
Module: Main
Entry point and CLI loop. Handles input/output, leaving all rule logic to Game.
Functions
1main()
2 game = setupGame()
3 game.start()
4 runGameLoop(game)
5
6setupGame() โ Game
7 -- prompt for number of players
8 -- prompt for each player's name and whether they are human or AI
9 -- return Game.create(names, humanFlags)
10
11runGameLoop(game)
12 -- loop until game.isOver():
13 printState(game)
14 takeTurn(game)
15 -- printFinalScores(game)
16
17takeTurn(game)
18 -- if currentPlayer is human: humanTurn(game)
19 -- else: aiTurn(game)
20
21humanTurn(game)
22 -- display hand to the player
23 -- prompt: choose a target player
24 -- prompt: choose a rank to ask for
25 -- result = game.ask(targetIndex, rank)
26 -- printResult(result)
27 -- if result.wentFishing:
28 result = game.goFish()
29 printResult(result)
30
31aiTurn(game)
32 -- target = currentPlayer.chooseTarget(otherPlayers)
33 -- rank = currentPlayer.chooseRank()
34 -- result = game.ask(target, rank)
35 -- printResult(result)
36 -- if result.wentFishing:
37 result = game.goFish()
38 printResult(result)
39
40printState(game)
41 -- show current player's name
42 -- show human player's hand (hide AI hands)
43 -- show book counts for all players
44 -- show cards remaining in deck
45
46printResult(result)
47 -- narrate what happened: who asked whom, for what, and the outcome
48
49printFinalScores(game)
50 -- display winner(s) and full score table
Data Flow Summary
1main
2 โโโ setupGame() โ creates Game
3 โโโ game.start() โ shuffle + deal
4 โโโ runGameLoop()
5 โโโ takeTurn()
6 โโโ humanTurn() or aiTurn()
7 โ โโโ game.ask(target, rank)
8 โ โโโ success โ cards transferred, check books
9 โ โ turnEnds = false โ ask again
10 โ โโโ "Go Fish" โ phase = GoFish
11 โ โโโ game.goFish() โ draw card, check book
12 โ advanceTurn()
13 โโโ (repeat until game.isOver())
Key Design Decisions
Turn continuation. When a player receives cards they ask again immediately. TurnResult.turnEnds signals whether the turn passes, keeping this logic inside Game rather than in the UI.
Book detection. hand.collectBooks() is called automatically after any cards are added, so the hand is always in a valid state.
AI extensibility. chooseRank and chooseTarget live on Player, making it easy to swap in a smarter strategy (e.g. memory of past asks) without touching Game.
Phase gating. ask and goFish validate the current phase before executing, preventing invalid sequences of calls regardless of how the UI is built.