blob: 344f362524874a7ecac5335ac6a96adef0539b63 [file] [log] [blame]
// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package rps defines interfaces for playing the game Rock-Paper-Scissors. It
// is an example of a simple Vanadium service.
//
// http://en.wikipedia.org/wiki/Rock-paper-scissors
//
// There are three different roles in the game:
//
// 1. Judge: A judge enforces the rules of the game and decides who the winner
// is. At the end of the game, the judge reports the final score to all the
// score keepers.
//
// 2. Player: A player can ask a judge to start a new game, it can challenge
// another player, and it can play a game.
//
// 3. ScoreKeeper: A score keeper receives the final score for a game after it
// ended.
package rps
import (
"time"
"v.io/v23/security/access"
)
type RockPaperScissors interface {
Judge
Player
ScoreKeeper
}
type Judge interface {
// CreateGame creates a new game with the given game options and returns a game
// identifier that can be used by the players to join the game.
CreateGame(Opts GameOptions) (GameId | error) {access.Write}
// Play lets a player join an existing game and play.
Play(Id GameId) stream<PlayerAction,JudgeAction> (PlayResult | error) {access.Write}
}
// A GameId is used to uniquely identify a game within one Judge.
type GameId struct {
Id string
}
// GameOptions specifies the parameters of a game.
type GameOptions struct {
NumRounds int32 // The number of rounds that a player must win to win the game.
GameType GameTypeTag // The type of game to play: Classic or LizardSpock.
}
type GameTypeTag byte
const (
Classic = GameTypeTag(0) // Rock-Paper-Scissors
LizardSpock = GameTypeTag(1) // Rock-Paper-Scissors-Lizard-Spock
)
type PlayerAction union {
Move string // The move that the player wants to make.
Quit Unused // Indicates that the player is quitting the game.
}
// TODO(toddw): Replace Unused with the unnamed empty struct{}.
type Unused struct{}
type JudgeAction union {
PlayerNum int32 // The player's number.
OpponentName string // The name of the opponent.
MoveOptions []string // A list of allowed moves that the player must choose from.
RoundResult Round // The result of the previous round.
Score ScoreCard // The result of the game.
}
type PlayersMoves [2]string
// Round represents the state of a round.
type Round struct {
Moves PlayersMoves // Each player's move.
Comment string // A text comment from judge about the round.
Winner WinnerTag // Who won the round.
StartTime time.Time // The time at which the round started.
EndTime time.Time // The time at which the round ended.
}
// WinnerTag is a type used to indicate whether a round or a game was a draw,
// was won by player 1 or was won by player 2.
type WinnerTag byte
const (
Draw = WinnerTag(0)
Player1 = WinnerTag(1)
Player2 = WinnerTag(2)
)
// PlayResult is the value returned by the Play method. It indicates the outcome of the game.
type PlayResult struct {
YouWon bool // True if the player receiving the result won the game.
}
// Player can receive challenges from other players.
type Player interface {
// Challenge is used by other players to challenge this player to a game. If
// the challenge is accepted, the method returns nil.
Challenge(Address string, Id GameId, Opts GameOptions) error {access.Write}
}
// ScoreKeeper receives the outcome of games from Judges.
type ScoreKeeper interface {
Record(Score ScoreCard) error {access.Write}
}
type ScoreCard struct {
Opts GameOptions // The game options.
Judge string // The name of the judge.
Players []string // The name of the players.
Rounds []Round // The outcome of each round.
StartTime time.Time // The time at which the game started.
EndTime time.Time // The time at which the game ended.
Winner WinnerTag // Who won the game.
}