1#!/usr/sbin/dtrace -wqs
2/*
3 * guess.d - guessing game in D (DTrace)
4 *
5 * 30-Nov-2005, ver 0.71
6 *
7 * USAGE: guess.d
8 *
9 * SEE: http://www.brendangregg.com/guessinggame.html
10 *
11 * This is written to demonstrate this language versus the same program
12 * written in other languages.
13 *
14 * 11-May-2005   Brendan Gregg   Created this.
15 */
16
17inline string scorefile = "highscores_d";
18
19dtrace:::BEGIN
20{
21	printf("guess.d - Guess a number between 1 and 100\n\n");
22	num = 1;
23	this->state = 1;
24
25	/* Generate random number */
26	answer = (rand() % 100) + 1;
27}
28
29syscall::write:entry
30/this->state == 1 && pid == $pid/
31{
32	this->state = 2;
33	printf("Enter guess %d: ", num);
34	system("read guess");
35	pos = 0;
36}
37
38syscall::read:entry
39/this->state == 2 && ppid == $pid && arg0 == 3/
40{
41	self->inguess = 1;
42	self->buf = arg1;
43}
44
45syscall::read:return
46/self->inguess/
47{
48	key = copyin(self->buf, arg0);
49	keys[pos] = *(char *)key;
50	self->buf = 0;
51	pos++;
52}
53
54syscall::read:return
55/self->inguess && keys[pos-1] == '\n'/
56{
57	pos -= 2;
58	fac = 1;
59	guess = fac * (keys[pos] - '0');
60	pos--;
61	fac *= 10;
62	guess = pos >= 0 ? guess + fac * (keys[pos] - '0') : guess;
63	pos--;
64	fac *= 10;
65	guess = pos >= 0 ? guess + fac * (keys[pos] - '0') : guess;
66	self->doneguess = 1;
67}
68
69syscall::read:return
70/self->inguess/
71{
72	self->inguess = 0;
73}
74
75/* Play game */
76syscall::read:return
77/self->doneguess && guess == answer/
78{
79	printf("Correct! That took %d guesses.\n\n", num);
80	self->doneguess = 0;
81	this->state = 3;
82	printf("Please enter your name: ");
83	system("/usr/bin/read name");
84}
85
86syscall::read:return
87/self->doneguess && guess != answer/
88{
89	num++;
90
91	printf("%s...\n", guess < answer ? "Higher" : "Lower");
92
93	printf("Enter guess %d: ", num);
94	system("read line");
95	pos = 0;
96}
97
98syscall::read:entry
99/this->state == 3 && curthread->t_procp->p_parent->p_ppid == $pid && arg0 == 0/
100{
101	self->inname = 1;
102	self->buf = arg1;
103}
104
105/* Save high score */
106syscall::read:return
107/self->inname/
108{
109	self->inname = 0;
110	name = stringof(copyin(self->buf, arg0 - 1));
111	system("echo %s %d >> %s", name, num, scorefile);
112
113	/* Print high scores */
114	printf("\nPrevious high scores,\n");
115	system("cat %s", scorefile);
116	exit(0);
117}
118