Update all new Tasks

This commit is contained in:
Ingy döt Net 2015-02-20 09:02:09 -05:00
parent 00a190b0a6
commit 91df62d461
5697 changed files with 93386 additions and 804 deletions

View file

@ -0,0 +1,18 @@
[[wp:Penney's_game|Penneys game]] is a game where two players bet on being the first to see a particular sequence of Heads and Tails in consecutive tosses of a fair coin.
It is common to agree on a sequence length of three then one player will openly choose a sequence, for example Heads, Tails, Heads, or HTH for short; then the other player on seeing the first players choice will choose his sequence. The coin is tossed and the first player to see his sequence in the sequence of coin tosses wins.
For example: One player might choose the sequence HHT and the other THT. Successive coin tosses of HTTHT gives the win to the second player as the last three coin tosses are his sequence.
;The Task:
Create a program that tosses the coin, keeps score and plays Penney's game against a human opponent.
* Who chooses and shows their sequence of three should be chosen randomly.
* If going first, the computer should choose its sequence of three randomly.
* If going second, the computer should automatically play [[wp:Penney's_game#Analysis_of_the_three-bit_game|the optimum sequence]].
* Successive coin tosses should be shown.
Show output of a game where the computer choses first and a game where the user goes first here on this page.
;Refs:
* [https://www.youtube.com/watch?v=OcYnlSenF04 The Penney Ante Part 1] (Video).
* [https://www.youtube.com/watch?v=U9wak7g5yQA The Penney Ante Part 2] (Video).

View file

@ -0,0 +1,86 @@
#include <time.h>
#include <iostream>
#include <string>
using namespace std;
class penney
{
public:
penney()
{ pW = cW = 0; }
void gameLoop()
{
string a;
while( true )
{
playerChoice = computerChoice = "";
if( rand() % 2 )
{ computer(); player(); }
else
{ player(); computer(); }
play();
cout << "[Y] to play again "; cin >> a;
if( a[0] != 'Y' && a[0] != 'y' )
{
cout << "Computer won " << cW << " times." << endl << "Player won " << pW << " times.";
break;
}
cout << endl << endl;
}
}
private:
void computer()
{
if( playerChoice.length() == 0 )
{
for( int x = 0; x < 3; x++ )
computerChoice.append( ( rand() % 2 ) ? "H" : "T", 1 );
}
else
{
computerChoice.append( playerChoice[1] == 'T' ? "H" : "T", 1 );
computerChoice += playerChoice.substr( 0, 2 );
}
cout << "Computer's sequence of three is: " << computerChoice << endl;
}
void player()
{
cout << "Enter your sequence of three (H/T) "; cin >> playerChoice;
}
void play()
{
sequence = "";
while( true )
{
sequence.append( ( rand() % 2 ) ? "H" : "T", 1 );
if( sequence.find( playerChoice ) != sequence.npos )
{
showWinner( 1 );
break;
}
else if( sequence.find( computerChoice ) != sequence.npos )
{
showWinner( 0 );
break;
}
}
}
void showWinner( int i )
{
string s;
if( i ) { s = "Player wins!"; pW++; }
else { s = "Computer wins!"; cW++; }
cout << "Tossed sequence: " << sequence << endl << s << endl << endl;
}
string playerChoice, computerChoice, sequence;
int pW, cW;
};
int main( int argc, char* argv[] )
{
srand( static_cast<unsigned>( time( NULL ) ) );
penney game; game.gameLoop();
return 0;
}

View file

@ -0,0 +1,121 @@
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define SEQLEN 3
int getseq(char *s)
{
int r = 0;
int i = 1 << (SEQLEN - 1);
while (*s && i) {
switch (*s++) {
case 'H':
case 'h':
r |= i;
break;
case 'T':
case 't':
/* 0 indicates tails, this is 0, so do nothing */
break;
default:
return -1;
}
i >>= 1;
}
return r;
}
void printseq(int seq)
{
int i;
for (i = SEQLEN - 1; i >= 0; --i)
printf("%c", seq & (1 << i) ? 'h' : 't');
}
int getuser(void)
{
int user;
char s[SEQLEN + 1];
printf("Enter your sequence of %d (h/t): ", SEQLEN);
while (1) {
/* This needs to be manually changed if SEQLEN is changed */
if (scanf("%3s", s) != 1) exit(1);
if ((user = getseq(s)) != -1) return user;
printf("Please enter only h/t characters: ");
}
}
int getai(int user)
{
int ai;
printf("Computers sequence of %d is: ", SEQLEN);
/* The ai's perfect choice will only be perfect for SEQLEN == 3 */
if (user == -1)
ai = rand() & (1 << SEQLEN) - 1;
else
ai = (user >> 1) | ((~user << 1) & (1 << SEQLEN - 1));
printseq(ai);
printf("\n");
return ai;
}
int rungame(int user, int ai)
{
/* Generate first SEQLEN flips. We only need to store the last SEQLEN
* tosses at any one time. */
int last3 = rand() & (1 << SEQLEN) - 1;
printf("Tossed sequence: ");
printseq(last3);
while (1) {
if (user == last3) {
printf("\nUser wins!\n");
return 1;
}
if (ai == last3) {
printf("\nAi wins!\n");
return 0;
}
last3 = ((last3 << 1) & (1 << SEQLEN) - 2) | (rand() & 1);
printf("%c", last3 & 1 ? 'h' : 't');
}
}
int main(void)
{
srand(time(NULL));
int playerwins = 0;
int totalgames = 0;
/* Just use ctrl-c for exit */
while (1) {
int user = -1;
int ai = -1;
printf("\n");
if (rand() & 1) {
ai = getai(user);
user = getuser();
}
else {
user = getuser();
ai = getai(user);
}
playerwins += rungame(user, ai);
totalgames++;
printf("You have won %d out of %d games\n", playerwins, totalgames);
printf("=================================\n");
}
return 0;
}

View file

@ -0,0 +1,35 @@
void main() {
import std.stdio, std.random, std.algorithm, std.string,
std.conv, std.range, core.thread;
immutable first = uniform(0, 2) == 0;
string you, me;
if (first) {
me = 3.iota.map!(_ => "HT"[uniform(0, $)]).text;
writefln("I choose first and will win on first seeing %s in the list of tosses", me);
while (you.length != 3 || you.any!(c => !c.among('H', 'T')) || you == me) {
"What sequence of three Heads/Tails will you win with: ".write;
you = readln.strip;
}
} else {
while (you.length != 3 || you.any!(c => !c.among('H', 'T'))) {
"After you: What sequence of three Heads/Tails will you win with: ".write;
you = readln.strip;
}
me = (you[1] == 'T' ? 'H' : 'T') ~ you[0 .. 2];
writefln("I win on first seeing %s in the list of tosses", me);
}
"Rolling:\n ".write;
string rolled;
while (true) {
rolled ~= "HT"[uniform(0, $)];
rolled.back.write;
if (rolled.endsWith(you))
return "\n You win!".writeln;
if (rolled.endsWith(me))
return "\n I win!".writeln;
Thread.sleep(1.seconds);
}
}

View file

@ -0,0 +1,91 @@
import qualified Data.List as L
import System.IO
import System.Random
data CoinToss = H | T deriving (Read, Show, Eq)
parseToss :: String -> [CoinToss]
parseToss [] = []
parseToss (s:sx)
| s == 'h' || s == 'H' = H : parseToss sx
| s == 't' || s == 'T' = T : parseToss sx
| otherwise = parseToss sx
notToss :: CoinToss -> CoinToss
notToss H = T
notToss T = H
instance Random CoinToss where
random g = let (b, gb) = random g in (if b then H else T, gb)
randomR = undefined
prompt :: (Read a) => String -> String -> (String -> Maybe a) -> IO a
prompt msg err parse = do
putStrLn msg
line <- getLine
let ans = parse line
case ans of
Nothing -> do
putStrLn err
prompt msg err parse
Just ansB -> return ansB
showCat :: (Show a) => [a] -> String
showCat = concatMap show
data Winner = Player | CPU
-- This may never terminate.
runToss :: (RandomGen g) => [CoinToss] -> [CoinToss] -> g -> ([CoinToss], Winner)
runToss player cpu gen =
let stream = randoms gen
run ss@(s:sx)
| L.isPrefixOf player ss = player
| L.isPrefixOf cpu ss = cpu
| otherwise = s : run sx
winner = run stream
in if L.isSuffixOf player winner
then (winner, Player)
else (winner, CPU)
game :: (RandomGen g, Num a, Show a) => Bool -> a -> a -> g -> IO ()
game cpuTurn playerScore cpuScore gen = do
putStrLn $ "\nThe current score is CPU: " ++ show cpuScore
++ ", You: " ++ show playerScore
let (genA, genB) = split gen
promptPlayer check =
prompt "Pick 3 coin sides: " "Invalid input." $ \s ->
let tosses = parseToss s in
if check tosses then Just tosses else Nothing
promptCpu x = putStrLn $ "I have chosen: " ++ showCat x
(tosses, winner) <-
if cpuTurn
then do
let cpuChoice = take 3 $ randoms gen
promptCpu cpuChoice
playerChoice <- promptPlayer $ \n -> n /= cpuChoice && 3 == length n
return $ runToss playerChoice cpuChoice genA
else do
playerChoice <- promptPlayer $ \n -> 3 == length n
let cpuChoice = case playerChoice of [a,b,_] -> [notToss b, a, b]
promptCpu cpuChoice
return $ runToss playerChoice cpuChoice genA
putStrLn $ "The sequence tossed was: " ++ showCat tosses
case winner of
Player -> do
putStrLn "You win!"
game (not cpuTurn) (playerScore + 1) cpuScore genB
CPU -> do
putStrLn "I win!"
game (not cpuTurn) playerScore (cpuScore + 1) genB
main :: IO ()
main = do
hSetBuffering stdin LineBuffering
stdgen <- getStdGen
let (cpuFirst, genA) = random stdgen
game cpuFirst 0 0 genA

View file

@ -0,0 +1,28 @@
require 'format/printf numeric'
randomize '' NB. randomize seed for new session
Vals=: 'HT' NB. valid values
input=: 1!:1@<&1: NB. get input from user
prompt=: input@echo NB. prompt user for input
checkInput=: 'Choose 3 H/Ts' assert (Vals e.~ ]) , 3 = #
getUserSeq=: (] [ checkInput)@toupper@prompt
choose1st=: Vals {~ 3 ?@$ 2: NB. computer chooses 1st
choose2nd=: (0 1 1=1 0 1{])&.(Vals&i.) NB. computer chooses 2nd
playPenney=: verb define
if. ?2 do. NB. randomize first chooser
Comp=. choose1st ''
'Computer chose %s' printf <Comp
You=. getUserSeq 'Choose a sequence of three coin tosses (H/T):'
'Choose a different sequence to computer' assert You -.@-: Comp
else.
You=. getUserSeq 'Choose a sequence of three coin tosses (H/T):'
Comp=. choose2nd You
'Computer chose %s ' printf <Comp
end.
Tosses=. Vals {~ 100 ?@$ 2
Result=. (Comp,:You) {.@I.@E."1 Tosses
'Toss sequence is %s' printf < (3 + <./ Result) {. Tosses
echo ('No result';'You win!';'Computer won!') {::~ *-/ Result
)

View file

@ -0,0 +1,12 @@
playPenney''
Computer chose TTT
Choose a sequence of three coin tosses (H/T):
HTT
Toss sequence is TTHHTT
You win!
playPenney''
Choose a sequence of three coin tosses (H/T):
HTT
Computer chose HHT
Toss sequence is HTHTT
You win!

View file

@ -0,0 +1,52 @@
import java.util.*;
public class PenneysGame {
public static void main(String[] args) {
Random rand = new Random();
String compChoice = "", playerChoice;
if (rand.nextBoolean()) {
for (int i = 0; i < 3; i++)
compChoice += "HT".charAt(rand.nextInt(2));
System.out.printf("Computer chooses %s%n", compChoice);
playerChoice = prompt(compChoice);
} else {
playerChoice = prompt(compChoice);
compChoice = "T";
if (playerChoice.charAt(1) == 'T')
compChoice = "H";
compChoice += playerChoice.substring(0, 2);
System.out.printf("Computer chooses %s%n", compChoice);
}
String tossed = "";
while (true) {
tossed += "HT".charAt(rand.nextInt(2));
System.out.printf("Tossed %s%n" , tossed);
if (tossed.endsWith(playerChoice)) {
System.out.println("You win!");
break;
}
if (tossed.endsWith(compChoice)) {
System.out.println("Computer wins!");
break;
}
}
}
private static String prompt(String otherChoice) {
Scanner sc = new Scanner(System.in);
String s;
do {
System.out.print("Choose a sequence: ");
s = sc.nextLine().trim().toUpperCase();
} while (!s.matches("[HT]{3}") || s.equals(otherChoice));
return s;
}
}

View file

@ -0,0 +1,72 @@
enum Coin <Heads Tails>;
enum Yay <Yay Good Super Hah Ooh Yipee Sweet Cool Yes Haha>;
enum Boo <Drat Darn Crumb Oops Rats Bah Criminy Argh Shards>;
enum Bozo «'Dude' 'Cha' 'Bzzt' 'Hey' 'Silly dilly' 'Say what!?' 'You numbskull'»;
sub flipping {
for 1..4 {
print "-\b"; sleep .1;
print "\\\b"; sleep .1;
print "|\b"; sleep .1;
print "/\b"; sleep .1;
}
}
sub your-choice($p is copy) {
loop (my @seq; @seq != 3; $p = "{Bozo.pick}! Please pick exactly 3: ") {
@seq = prompt($p).uc.comb(/ H | T /).map: {
when 'H' { Heads }
when 'T' { Tails }
}
}
@seq;
}
repeat until prompt("Wanna play again? ").lc ~~ /^n/ {
my $mefirst = Coin.roll;
print tc "$mefirst I start, {Coin(+!$mefirst).lc} you start, flipping...\n\t";
flipping;
say my $flip = Coin.roll;
my @yours;
my @mine;
if $flip == $mefirst {
print "{Yay.pick}! I get to choose first, and I choose: "; sleep 2; say @mine = Coin.roll(3);
@yours = your-choice("Now you gotta choose: ");
while @yours eqv @mine {
say "{Bozo.pick}! We'd both win at the same time if you pick that!";
@yours = your-choice("Pick something different from me: ");
}
say "So, you'll win if we see: ", @yours;
}
else {
@yours = your-choice("{Boo.pick}! First you choose: ");
say "OK, you'll win if we see: ", @yours;
print "In that case, I'll just randomly choose: "; sleep 2; say @mine = Coin(+!@yours[1]), @yours[0,1];
}
sub check($a,$b,$c) {
given [$a,$b,$c] {
when @mine { say "\n{Yay.pick}, I win, and you lose!"; Nil }
when @yours { say "\n{Boo.pick}, you win, but I'll beat you next time!"; Nil }
default { Coin.roll }
}
}
sleep 1;
say < OK! Ready? Right... So... Yo!>.pick;
sleep .5;
say ("Pay attention now!",
"Watch closely!",
"Let's do it...",
"You feeling lucky?",
"No way you gonna win this...",
"Can I borrow that coin again?").pick;
sleep 1;
print "Here we go!\n\t";
for Coin.roll(3), &check ...^ :!defined {
flipping;
print "$_ ";
}
}

View file

@ -0,0 +1,30 @@
from __future__ import print_function
import random
from time import sleep
first = random.choice([True, False])
you = ''
if first:
me = ''.join(random.sample('HT'*3, 3))
print('I choose first and will win on first seeing {} in the list of tosses'.format(me))
while len(you) != 3 or any(ch not in 'HT' for ch in you) or you == me:
you = input('What sequence of three Heads/Tails will you win with: ')
else:
while len(you) != 3 or any(ch not in 'HT' for ch in you):
you = input('After you: What sequence of three Heads/Tails will you win with: ')
me = ('H' if you[1] == 'T' else 'T') + you[:2]
print('I win on first seeing {} in the list of tosses'.format(me))
print('Rolling:\n ', end='')
rolled = ''
while True:
rolled += random.choice('HT')
print(rolled[-1], end='')
if rolled.endswith(you):
print('\n You win!')
break
if rolled.endswith(me):
print('\n I win!')
break
sleep(1) # For dramatic effect

1
Task/Penneys-game/README Normal file
View file

@ -0,0 +1 @@
Data source: http://rosettacode.org/wiki/Penney's_game

View file

@ -0,0 +1,67 @@
/*REXX program plays Penney's Game, a 2-player coin toss sequence game.*/
__=copies('',9) /*literal for eyecatching fence. */
signal on halt /*a clean way out if CLBF quits. */
parse arg # ? . /*get optional args from the C.L.*/
if #=='' | #=="," then #=3 /*default coin sequence length. */
if ?\=='' & ?\==',' then call random ,,? /*use seed for RANDOM #s ?*/
wins=0; do games=1 /*play a number of Penney's games*/
call game /*play a single inning of a game.*/
end /*games*/ /*keep at it 'til QUIT or halt.*/
exit /*stick a fork in it, we're done.*/
/*──────────────────────────────────one-line subroutines────────────────*/
halt: say; say __ "Penney's Game was halted."; say; exit 13
r: arg ,$; do arg(1); $=$||random(0,1); end; return $
s: if arg(1)==1 then return arg(3); return word(arg(2) 's',1) /*plural*/
/*──────────────────────────────────GAME subroutine─────────────────────*/
game: @.=; tosses=@. /*the coin toss sequence so far. */
toss1=r(1) /*result: 0=computer, 1=CBLF.*/
if \toss1 then call randComp /*maybe let the computer go first*/
if toss1 then say __ "You win the first toss, so you pick your sequence first."
else say __ "The computer won first toss, the pick was: " @.comp
call prompter /*get the human's guess from C.L.*/
call randComp /*get computer's guess if needed.*/
/*CBLF: carbon-based life form. */
say __ " your pick:" @.CBLF /*echo human's pick to terminal. */
say __ "computer's pick:" @.comp /* " comp.'s " " " */
say /* [↓] flip the coin 'til a win.*/
do flips=1 until pos(@.CBLF,tosses)\==0 | pos(@.comp,tosses)\==0
tosses=tosses || translate(r(1),'HT',10)
end /*flips*/ /* [↑] this is a flipping coin,*/
/* [↓] series of tosses*/
say __ "The tossed coin series was: " tosses /*show the coin tosses.*/
say
@@@="won this toss with " flips ' coin tosses.' /*handy literal.*/
if pos(@.CBLF,tosses)\==0 then do; say __ "You" @@@; wins=wins+1; end
else say __ "The computer" @@@
_=wins; if _==0 then _='no' /*use gooder English.*/
say __ "You've won" _ "game"s(wins) 'out of ' games"."
say; say copies('',79%2)''; say /*show eyeball fence.*/
return
/*──────────────────────────────────PROMPTER subroutine─────────────────*/
prompter: oops=__ 'Oops! '; a= /*define some handy REXX literals*/
@a_z='ABCDEFG-IJKLMNOPQRS+UVWXYZ' /*the extraneous alphabetic chars*/
p=__ 'Pick a sequence of' # "coin tosses of H or T (Heads or Tails) or Quit:"
do until ok; say; say p; pull a /*uppercase the answer.*/
if abbrev('QUIT',a,1) then exit 1 /*human wants to quit. */
a=space(translate(a,,@a_z',./\;:_'),0) /*elide extraneous chrs*/
b=translate(a,10,'HT'); L=length(a) /*tran───►bin; get len.*/
ok=0 /*response is OK so far*/
select /*verify user response.*/
when \datatype(b,'B') then say oops "Illegal response."
when \datatype(a,'M') then say oops "Illegal characters in response."
when L==0 then say oops "No choice was given."
when L<# then say oops "Not enough coin choices."
when L># then say oops "Too many coin choices."
when a==@.comp then say oops "You can't choose the computer's choice: " @.comp
otherwise ok=1
end /*select*/
end /*until ok*/
@.CBLF=a; @.CBLF!=b /*we have the human's guess now. */
return
/*──────────────────────────────────RANDCOMP subroutine─────────────────*/
randComp: if @.comp\=='' then return /*the computer already has a pick*/
_=@.CBLF! /* [↓] use best-choice algorithm.*/
if _\=='' then g=left((\substr(_,min(2,#),1))left(_,1)substr(_,3),#)
do until g\==@.CBLF!; g=r(#); end /*otherwise, generate a choice. */
@.comp=translate(g,'HT',10)
return

View file

@ -0,0 +1,37 @@
#lang racket
;; Penney's Game. Tim Brown 2014-10-15
(define (flip . _) (match (random 2) (0 "H") (1 "T")))
(define (get-human-sequence) ; no sanity checking here!
(display "choose your winning sequence of 3 H or T > ")
(drop-right (drop (string-split (string-upcase (read-line)) "") 1) 1))
(define flips->string (curryr string-join "."))
(define (game-on p1 p2)
(printf "~a chooses: ~a. ~a chooses: ~a~%"
(car p1) (flips->string (cdr p1)) (car p2) (flips->string (cdr p2)))
(match-define (list (list name.1 p1.1 p1.2 p1.3) (list name.2 p2.1 p2.2 p2.3)) (list p1 p2))
(let turn ((seq null))
(match seq
[(list-rest (== p1.3) (== p1.2) (== p1.1) _) name.1]
[(list-rest (== p2.3) (== p2.2) (== p2.1) _) name.2]
[else
(let* ((flp (flip)) (seq+ (cons flp else)))
(printf "new-flip: ~a -> ~a~%" flp (flips->string (reverse seq+))) (turn seq+))])))
(define (play-game)
(define-values
(player-1 player-2)
(match (flip)
["H" (printf "Human chooses first: ")
(define p1 (cons 'Hom-Sap (get-human-sequence)))
(values p1 (cons 'Computer
(match p1
[(list _ f1 (and f2 (app (match-lambda ("H" "T") ("T" "H")) ¬f2)) _)
(list ¬f2 f1 f2)])))]
["T" (printf "Computer chooses first. ")
(define p1 (cons 'Computer (build-list 3 flip)))
(printf "~a chooses: ~a~%" (car p1) (flips->string (cdr p1)))
(values p1 (cons 'Hom-Sap (get-human-sequence)))]))
(printf "~a wins!~%" (game-on player-1 player-2)))

View file

@ -0,0 +1,35 @@
# Penney's Game
Toss = [:Heads, :Tails]
def yourChoice
puts "Enter your choice (H/T)"
choice = []
3.times do
until (c = $stdin.getc.upcase) == "H" or c == "T"
end
choice << (c=="H" ? Toss[0] : Toss[1])
end
puts "You chose #{choice.join(' ')}"
choice
end
puts "%s I start, %s you start ..... #{coin = Toss.sample}" % Toss
if coin == Toss[0]
myC = Array.new(3){Toss.sample}
puts "I chose #{myC.join(' ')}"
yC = yourChoice
else
yC = yourChoice
myC = Toss - [yC[1]] + yC.first(2)
puts "I chose #{myC.join(' ')}"
end
seq = Array.new(3){Toss.sample}
print seq.join(' ')
loop do
puts "\n I win!" or break if seq == myC
puts "\n You win!" or break if seq == yC
seq.push(Toss.sample).shift
print " #{seq[-1]}"
end

View file

@ -0,0 +1,98 @@
package require Tcl 8.6
oo::class create Player {
variable who seq seen idx
constructor {name sequence} {
set who $name
set seq $sequence
set seen {}
set idx end-[expr {[string length $seq] - 1}]
}
method pick {} {
return $seq
}
method name {} {
return $who
}
method match {digit} {
append seen $digit
return [expr {[string range $seen $idx end] eq $seq}]
}
}
oo::class create HumanPlayer {
superclass Player
constructor {length {otherPlayersSelection ""}} {
fconfigure stdout -buffering none
while true {
puts -nonewline "What do you pick? (length $length): "
if {[gets stdin pick] < 0} exit
set pick [regsub -all {[^HT]} [string map {0 H 1 T h H t T} $pick] ""]
if {[string length $pick] eq $length} break
puts "That's not a legal pick!"
}
set name "Human"
if {[incr ::humans] > 1} {append name " #$::humans"}
next $name $pick
}
}
oo::class create RobotPlayer {
superclass Player
constructor {length {otherPlayersSelection ""}} {
if {$otherPlayersSelection eq ""} {
set pick ""
for {set i 0} {$i < $length} {incr i} {
append pick [lindex {H T} [expr {int(rand()*2)}]]
}
} else {
if {$length != 3} {
error "lengths other than 3 not implemented"
}
lassign [split $otherPlayersSelection ""] a b c
set pick [string cat [string map {H T T H} $b] $a $b]
}
set name "Robot"
if {[incr ::robots] > 1} {append name " #$::robots"}
puts "$name picks $pick"
next $name $pick
}
}
proc game {length args} {
puts "Let's play Penney's Game!"
# instantiate the players
set picks {}
set players {}
while {[llength $args]} {
set idx [expr {int(rand()*[llength $args])}]
set p [[lindex $args $idx] new $length {*}$picks]
set args [lreplace $args $idx $idx]
lappend players $p
lappend picks [$p pick]
}
# sanity check
if {[llength $picks] != [llength [lsort -unique $picks]]} {
puts "Two players picked the same thing; that's illegal"
}
# do the game loop
while 1 {
set coin [lindex {H T} [expr {int(rand()*2)}]]
puts "Coin flip [incr counter] is $coin"
foreach p $players {
if {[$p match $coin]} {
puts "[$p name] has won!"
return
}
}
}
}
game 3 HumanPlayer RobotPlayer

View file

@ -0,0 +1,70 @@
#!/bin/bash
main() {
echo "Penney's Game"
echo -n "Flipping to see who goes first ... "
if [[ $(flip) == H ]]; then
echo "I do."
p2=$(choose_sequence)
echo "I choose: $p2"
else
echo "You do."
fi
while true; do
echo "Enter your three-flip sequence:"
read p1
case "$p1" in
"$p2") echo "Sequence must be different from mine";;
[hHTt][hHtT][hHtT]) break;;
*) echo "Sequence must be three H's or T's";;
esac
done
p1=$(tr a-z A-Z <<<"$p1")
if [ -z "$p2" ]; then
p2=$(choose_sequence "$p1")
echo "I choose: $p2"
fi
echo
echo "Here we go. $p1, you win; $p2, I win."
flips=
while true; do
flip=$(flip)
echo -n $flip
flips+=$flip
while (( ${#flips} > 3 )); do
flips="${flips#?}"
done
case "$flips" in
*$p1) echo $'\nYou win!'; exit 0;;
*$p2) echo $'\nI win!'; exit 1;;
esac
done
}
choose_sequence() {
local result
if (( $# )); then
case "$1" in
?Hh?) result=T;;
*) result=H;;
esac
result+="${1%?}"
else
result=$(flip)$(flip)$(flip)
fi
echo "$result"
}
flip() {
if (( RANDOM % 2 )); then
echo H
else
echo T
fi
}
main "$@"