1235368Sgnn#!/usr/sbin/dtrace -wqs
2235368Sgnn/*
3235368Sgnn * guess.d - guessing game in D (DTrace)
4235368Sgnn *
5235368Sgnn * $Id: guess.d 32 2007-09-15 05:08:49Z brendan $
6235368Sgnn *
7235368Sgnn * USAGE: guess.d
8235368Sgnn *
9235368Sgnn * SEE: http://www.brendangregg.com/guessinggame.html
10235368Sgnn *
11235368Sgnn * This is written to demonstrate this language versus the same program
12235368Sgnn * written in other languages.
13235368Sgnn *
14235368Sgnn * 11-May-2005	Brendan Gregg	Created this.
15235368Sgnn */
16235368Sgnn
17235368Sgnninline string scorefile = "highscores_d";
18235368Sgnn
19235368Sgnndtrace:::BEGIN
20235368Sgnn{
21235368Sgnn	printf("guess.d - Guess a number between 1 and 100\n\n");
22235368Sgnn	num = 1;
23235368Sgnn	state = 1;
24235368Sgnn
25235368Sgnn	/* Generate random number */
26235368Sgnn	answer = (rand() % 100) + 1;
27235368Sgnn	answer = answer > 0 ? answer : - answer;
28235368Sgnn}
29235368Sgnn
30235368Sgnnsyscall::write:entry
31235368Sgnn/state == 1 && pid == $pid/
32235368Sgnn{
33235368Sgnn	state = 2;
34235368Sgnn	printf("Enter guess %d: ", num);
35235368Sgnn	system("read guess");
36235368Sgnn	pos = 0;
37235368Sgnn}
38235368Sgnn
39235368Sgnnsyscall::read:entry
40235368Sgnn/state == 2 && ppid == $pid && arg0 == 3/
41235368Sgnn{
42235368Sgnn	self->inguess = 1;
43235368Sgnn	self->buf = arg1;
44235368Sgnn}
45235368Sgnn
46235368Sgnnsyscall::read:return
47235368Sgnn/self->inguess/
48235368Sgnn{
49235368Sgnn	key = copyin(self->buf, arg0);
50235368Sgnn	keys[pos] = *(char *)key;
51235368Sgnn	self->buf = 0;
52235368Sgnn	pos++;
53235368Sgnn}
54235368Sgnn
55235368Sgnnsyscall::read:return
56235368Sgnn/self->inguess && keys[pos-1] == '\n'/
57235368Sgnn{
58235368Sgnn	pos -= 2;
59235368Sgnn	fac = 1;
60235368Sgnn	guess = fac * (keys[pos] - '0');
61235368Sgnn	pos--;
62235368Sgnn	fac *= 10;
63235368Sgnn	guess = pos >= 0 ? guess + fac * (keys[pos] - '0') : guess;
64235368Sgnn	pos--;
65235368Sgnn	fac *= 10;
66235368Sgnn	guess = pos >= 0 ? guess + fac * (keys[pos] - '0') : guess;
67235368Sgnn	self->doneguess = 1;
68235368Sgnn}
69235368Sgnn
70235368Sgnnsyscall::read:return
71235368Sgnn/self->inguess/
72235368Sgnn{
73235368Sgnn	self->inguess = 0;
74235368Sgnn}
75235368Sgnn
76235368Sgnn/* Play game */
77235368Sgnnsyscall::read:return
78235368Sgnn/self->doneguess && guess == answer/
79235368Sgnn{
80235368Sgnn	printf("Correct! That took %d guesses.\n\n", num);
81235368Sgnn	self->doneguess = 0;
82235368Sgnn	state = 3;
83235368Sgnn	printf("Please enter your name: ");
84235368Sgnn	system("/usr/bin/read name");
85235368Sgnn}
86235368Sgnn
87235368Sgnnsyscall::read:return
88235368Sgnn/self->doneguess && guess != answer/
89235368Sgnn{
90235368Sgnn	num++;
91235368Sgnn
92235368Sgnn	printf("%s...\n", guess < answer ? "Higher" : "Lower");
93235368Sgnn
94235368Sgnn	printf("Enter guess %d: ", num);
95235368Sgnn	system("read line");
96235368Sgnn	pos = 0;
97235368Sgnn}
98235368Sgnn
99235368Sgnnsyscall::read:entry
100235368Sgnn/state == 3 && curthread->t_procp->p_parent->p_ppid == $pid && arg0 == 0/
101235368Sgnn{
102235368Sgnn	self->inname = 1;
103235368Sgnn	self->buf = arg1;
104235368Sgnn}
105235368Sgnn
106235368Sgnn/* Save high score */
107235368Sgnnsyscall::read:return
108235368Sgnn/self->inname/
109235368Sgnn{
110235368Sgnn	self->inname = 0;
111235368Sgnn	name = stringof(copyin(self->buf, arg0 - 1));
112235368Sgnn	system("echo %s %d >> %s", name, num, scorefile);
113235368Sgnn
114235368Sgnn	/* Print high scores */
115235368Sgnn	printf("\nPrevious high scores,\n");
116235368Sgnn	system("cat %s", scorefile);
117235368Sgnn	exit(0);
118235368Sgnn}
119