blob: da8f9e78d732ec5668b1a5a076eb3e6685466ffa [file] [log] [blame]
// Package common factors out common utility functions that both the
// rock paper scissors clients and servers invoke.
package common
import (
"bytes"
"errors"
"fmt"
"math/rand"
"os"
"time"
"v.io/apps/rps"
"v.io/core/veyron2"
"v.io/core/veyron2/context"
"v.io/core/veyron2/naming"
"v.io/core/veyron2/vlog"
)
// CreateName creates a name using the username and hostname.
func CreateName() string {
hostname, err := os.Hostname()
if err != nil {
vlog.Fatalf("os.Hostname failed: %v", err)
}
return os.Getenv("USER") + "@" + hostname
}
// FindJudge returns a random rock-paper-scissors judge from the mount table.
func FindJudge(ctx *context.T) (string, error) {
judges, err := findAll(ctx, "judge")
if err != nil {
return "", err
}
if len(judges) > 0 {
return judges[rand.Intn(len(judges))], nil
}
return "", errors.New("no judges")
}
// FindPlayer returns a random rock-paper-scissors player from the mount table.
func FindPlayer(ctx *context.T) (string, error) {
players, err := findAll(ctx, "player")
if err != nil {
return "", err
}
if len(players) > 0 {
return players[rand.Intn(len(players))], nil
}
return "", errors.New("no players")
}
// FindScoreKeepers returns all the rock-paper-scissors score keepers from the
// mount table.
func FindScoreKeepers(ctx *context.T) ([]string, error) {
sKeepers, err := findAll(ctx, "scorekeeper")
if err != nil {
return nil, err
}
return sKeepers, nil
}
func findAll(ctx *context.T, t string) ([]string, error) {
start := time.Now()
ns := veyron2.GetNamespace(ctx)
c, err := ns.Glob(ctx, "rps/"+t+"/*")
if err != nil {
vlog.Infof("mt.Glob failed: %v", err)
return nil, err
}
var servers []string
for e := range c {
switch v := e.(type) {
case *naming.GlobError:
vlog.VI(1).Infof("findAll(%q) error for %q: %v", t, v.Name, v.Error)
case *naming.MountEntry:
servers = append(servers, v.Name)
}
}
vlog.VI(1).Infof("findAll(%q) elapsed: %s", t, time.Now().Sub(start))
return servers, nil
}
// FormatScoreCard returns a string representation of a score card.
func FormatScoreCard(score rps.ScoreCard) string {
buf := bytes.NewBufferString("")
var gameType string
switch score.Opts.GameType {
case rps.Classic:
gameType = "Classic"
case rps.LizardSpock:
gameType = "LizardSpock"
default:
gameType = "Unknown"
}
fmt.Fprintf(buf, "Game Type: %s\n", gameType)
fmt.Fprintf(buf, "Number of rounds: %d\n", score.Opts.NumRounds)
fmt.Fprintf(buf, "Judge: %s\n", score.Judge)
fmt.Fprintf(buf, "Player 1: %s\n", score.Players[0])
fmt.Fprintf(buf, "Player 2: %s\n", score.Players[1])
for i, r := range score.Rounds {
roundOffset := time.Duration(r.StartTimeNS - score.StartTimeNS)
roundTime := time.Duration(r.EndTimeNS - r.StartTimeNS)
fmt.Fprintf(buf, "Round %2d: Player 1 played %-10q. Player 2 played %-10q. Winner: %d %-28s [%-10s/%-10s]\n",
i+1, r.Moves[0], r.Moves[1], r.Winner, r.Comment, roundOffset, roundTime)
}
fmt.Fprintf(buf, "Winner: %d\n", score.Winner)
fmt.Fprintf(buf, "Time: %s\n", time.Duration(score.EndTimeNS-score.StartTimeNS))
return buf.String()
}