Skip to content

Commit

Permalink
Add random bot. Fix bug where cards run out.
Browse files Browse the repository at this point in the history
  • Loading branch information
marianogappa committed Jun 27, 2024
1 parent ad383b8 commit 4b6c0a9
Show file tree
Hide file tree
Showing 5 changed files with 97 additions and 12 deletions.
51 changes: 51 additions & 0 deletions examplebot/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package examplebot

import (
"fmt"
"log"
"math/rand"

"github.com/gorilla/websocket"
"github.com/marianogappa/truco/server"
"github.com/marianogappa/truco/truco"
)

func Bot(playerID int, address string) {
// Open the WebSocket connection, and send a hello message.

conn, _, err := websocket.DefaultDialer.Dial(fmt.Sprintf("ws://%v/ws", address), nil)
if err != nil {
log.Fatalf("Failed to connect to WebSocket server: %v", err)
}
defer conn.Close()

// Hello message is meant to tell the server who we are, and request game state.
// Game could be in progress (this could be a reconnection).
if err := server.WsSend(conn, server.NewMessageHello(playerID)); err != nil {
log.Fatal(err)
}

// On each iteration
for {
clientGameState, err := server.WsReadMessage[truco.ClientGameState, server.MessageHeresGameState](conn, server.MessageTypeHeresGameState)
if err != nil {
log.Fatal(err)
}

if clientGameState.IsGameEnded {
return
}

if clientGameState.TurnPlayerID != playerID {
continue
}

// Get a random element from clientGameState.PossibleActions.
randomAction := clientGameState.PossibleActions[rand.Intn(len(clientGameState.PossibleActions))]

// Send the action to the server.
if err := server.WsSend(conn, server.MessageAction{WebsocketMessage: server.WebsocketMessage{Type: server.MessageTypeAction}, Action: randomAction}); err != nil {
log.Fatal(err)
}
}
}
4 changes: 4 additions & 0 deletions exampleclient/ui.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"encoding/json"
"fmt"
"strings"
"time"

"github.com/marianogappa/truco/truco"
"github.com/nsf/termbox-go"
Expand Down Expand Up @@ -88,6 +89,9 @@ func (u *ui) render(state truco.ClientGameState, mode renderMode) error {
renderActions(rs)

termbox.Flush()
// This is an artificial delay to make the game more human-like.
time.Sleep(1 * time.Second)

return nil
}

Expand Down
49 changes: 37 additions & 12 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,37 +3,62 @@ package main
import (
"fmt"
"os"
"strconv"

"github.com/marianogappa/truco/examplebot"
"github.com/marianogappa/truco/exampleclient"
"github.com/marianogappa/truco/server"
)

func main() {
if len(os.Args) < 2 {
fmt.Println("usage: truco server")
fmt.Println("usage: truco player1|player2 [address]")
fmt.Println("Define the PORT environment variable for truco server to change the default port (8080).")
os.Exit(0)
usage()
}
port := os.Getenv("PORT")
if port == "" {
port = "8080"
}

cmd := os.Args[1]

address := fmt.Sprintf("localhost:%v", port)
if len(os.Args) >= 3 {
address = os.Args[2]
if len(os.Args) >= 4 {
address = os.Args[3]
}

var (
playerNum int
err error
)
if cmd == "player" || cmd == "bot" {
playerNum, err = strconv.Atoi(os.Args[2])
if err != nil {
fmt.Println("Invalid player number. Please provide a number.")
usage()
}
}

arg := os.Args[1]
switch arg {
switch cmd {
case "server":
server.New(port).Start()
case "player1":
exampleclient.Player(0, address)
case "player2":
exampleclient.Player(1, address)
case "player":
exampleclient.Player(playerNum-1, address)
case "bot":
examplebot.Bot(playerNum-1, address)
default:
fmt.Println("Invalid argument. Please provide either server or client.")
}
}

func usage() {
fmt.Println("usage: truco server")
fmt.Println("usage: truco player %number [address]")
fmt.Println("usage: truco bot %number [address]")
fmt.Println("usage: e.g. truco player 1")
fmt.Println("usage: e.g. truco player 2")
fmt.Println("usage: e.g. truco player 1 localhost:8080")
fmt.Println("usage: e.g. truco bot 1 localhost:8080")
fmt.Println("usage: e.g. truco bot 2")
fmt.Println("Define the PORT environment variable for truco server to change the default port (8080).")
os.Exit(1)
}
4 changes: 4 additions & 0 deletions truco/deck.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,10 @@ func newDeck() *deck {
return &d
}

func (d *deck) shuffle() {
d.cards = makeSpanishCards()
}

func (d *deck) dealHand() *Hand {
return d.dealHandFunc()
}
Expand Down
1 change: 1 addition & 0 deletions truco/truco.go
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ func New(opts ...func(*GameState)) *GameState {
}

func (g *GameState) startNewRound() {
g.deck.shuffle()
g.RoundTurnPlayerID = g.OpponentOf(g.RoundTurnPlayerID)
g.RoundNumber++
g.TurnPlayerID = g.RoundTurnPlayerID
Expand Down

0 comments on commit 4b6c0a9

Please sign in to comment.