Go Back   Forums > Community Chatterbox > Tech Corner > Programming
Memberlist Forum Rules Search Today's Posts Mark Forums Read
Search Forums:
Click here to use Advanced Search

Reply
 
Thread Tools Display Modes
Old 10-06-2006, 01:49 PM   #11
Reup
10 GOSUB Abandonia
20 GOTO 10
 
Reup's Avatar

 
Join Date: Dec 2004
Location: Nuenen, Netherlands
Posts: 1,508
Default

As I recall I didn't say there was anything against procedural programming, only that it was more old-fashioned then OO. I'm also aware that it's not the only and best way. I was merely asking about guesst preference.
Maybe we sould start a 'which paradigm rocks donkey-balls' thread to discuss the benefits of each one?
Reup is offline                         Send a private message to Reup
Reply With Quote
Old 10-06-2006, 02:37 PM   #12
guesst
Abandonia Homie
 
guesst's Avatar

 
Join Date: May 2005
Location: Aurora, United States
Posts: 606
Default

Boys, now, let's calm down. No paradgm bashing here.

@ Reup, you haven't voted.

I chose plain C because it's a place to start. In fact, it's where I started. I was esentally going back to my roots. The plan was for me to write a few programs in C, then move on to CPP. However, it didn't last that long. When I started getting ready to do Wumpus in CPP, an exelent program to do OO, and life got in the way. That was a few months ago. Some day, soon I hope, I'll be able to finish what I started and show some CPP programs. Then I'm going to start simple graphical programs, then take over the world.
guesst is offline                         Send a private message to guesst
Reply With Quote
Old 12-06-2006, 08:33 PM   #13
guesst
Abandonia Homie
 
guesst's Avatar

 
Join Date: May 2005
Location: Aurora, United States
Posts: 606
Default

Well, I've gotten a single vote and that's probably going to be it. So here you go, by popular request:
Four in a Row
This was a algorithm adapted directly from a BASIC program and is uniquely frustrating because I've played it tons of times and only beaten it once.

The page in the link for the BASIC program above explains a little bit about the procedure the computer takes when making a move. I'll explain a bit after the code. So without further ado:
Code:
/* 4inarow
 * by Joseph Larson
 * based on a BASIC game by James L. Murphy
 * as found in 'More BASIC Computer Games' by David H. Ahl (c) 1979
 */

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>

#define SHOWBD for (c=9; c >= 0; c--) puts (bd[c])
#define _X 'X'
#define _O 'O'

unsigned long v[16] = {1, 75, 500, 1e9, 1, 800, 4000, 1e9
**********************,1,100, 900, 1e7, 1, 450, 3000, 1e7};
int inrow[4], open[4], h[8];
char bd[9][20];

void intro (void) {
**puts ("Four in a Row\n---- -- - ---\n"
**"Stack X's and O's in order to make 4 in a row either vertically,\n"
**"horizontally diagonally before your opponent does.\n");
}

void init (void) {
**int c;

**for (c = 0; c < 8;) {
****h[c] = 0;
****strcpy (bd[++c], "- - - - - - - - ");
**}
**strcpy (bd[0], "1 2 3 4 5 6 7 8 ");
}

int count (int x, int y, char token) {
**int w, k, dx, dy, cx, cy, c, t;
**char op;

**x *= 2; op = (token - _X) ? _X : _O;
**for (c = 0; c < 4; c++) {
****inrow[c] = 1; open[c] = 0;
****dx = 2 * (c - 1 - (c > 2));
****dy = (c != 3);
****for (w = 0; w < 2; w++) {
******t = 1;
******for (k = 1; k < 4 && bd [cy = y + dy * k][cx = x + dx * k] != op; k++)
********if (cx <= 15 && cx >= 0 && cy <= 8 && cy > 0) {
**********if (t && bd[cy][cx] == token) inrow[c]++;
**********else {open[c]++; t = 0;}
********}
******dx = -dx; dy = -dy;
****}
****if (inrow[c] > 3) return 1;
**}
**k = 0;
**for (c = 0; c < 8; c++) if (h[c] < 8) k++;
**if (!k) return 2;
**return 0;
}

int domove (int m, char token) {
**bd [++h[m]][2 * m] = token;
**return count (m, h[m], token);
}

int getmove (int pl) {
**int input = 0;

**do {
****if (input) puts ("Illegal move, try again.");
****printf ("Player %d, pick a column (1 - 8) ? ", pl); scanf ("%d", &input);
****if (input < 1 || input > 8 || h[input - 1] > 7) input = -1;
**} while (input < 0);
**return --input;
}

int compmove (void) {
**unsigned long rank, bestrank;
**int bestmove, w, x, y, c, n[4], numsame;
**char token;

**bestmove = bestrank = 0; numsame = 1;
**for (x = 0; x < 8; x++) {
****y = h[x] + 1;
****if (y < 9) {
******rank = 1; token = _O;
******for (w = 0; w < 2; w++) {
********if (count (x, y, token)) {
**********printf ("Computer picks column %d\n", x + 1); return x;
********}
********for (c = 0; c < 4; c++) n[c] = 0;
********for (c = 0; c < 4; c++) {
**********open[c] += inrow[c];
**********if (open[c] > 3) {rank += 4; n[inrow[c] - 1]++;}
********}
********for (c = 0; c < 4; c++) if (n[c]--)
**********rank += v[8 * w + 4 * (n[c] ? 1 : 0) + c] + n[c] * v[8 * w + c];
********token = _X;
******}
******if (y < 8) if (count(x, y + 1, token)) rank = 2;
******if (rank == bestrank) if (rand() < RAND_MAX / ++numsame) {
********bestrank = rank; bestmove = x;
******}
****}
****if (rank > bestrank) {bestrank = rank; bestmove = x; numsame = 1;}
**}
**printf ("Computer picks column %d\n", bestmove + 1);
**return bestmove;
}

int main (void) {
**int c, numpl, w = 0;
**
**intro ();
**srand (time (NULL));
**init ();
**printf ("One or two human players? (1/2) "); scanf ("%d", &numpl);
**while (numpl > 2 || numpl < 1) {
****printf ("Please type the number 1 or 2 ? "); scanf ("%d", &numpl);
**}
**if (!--numpl) puts ("The Computer will be Player 2.");
**if (rand () % 2) {
****puts ("Player 1 goes first.");
****SHOWBD;
****domove (getmove (1), _X);
**} else puts ("Player 2 goes first.");
**while (!w) {
****SHOWBD;
****if (!(w = domove ((numpl) ? getmove (2) : compmove (), _O))) {
******SHOWBD;
******w = domove (getmove (1), _X);
****} else if (w == 1) w = 3;
**}
**SHOWBD;
**switch (w) {
****case 1 : puts ("Player 1 wins!"); break;
****case 2 : puts ("Tie game."); break;
****case 3 : puts ("Player 2 wins!");
**}
**exit (0);
}
A few notes about the code. The main funciton is a bit bigger than some programmers like to see. I suppose it could have been relegated to a sub routine, and still could I suppose. But I was experimenting with different styles of coding and this happened to be the one I chose at the time. It works, so meh.

How the computer makes a move. First of all, the board data is maintained in strings so that outputting the board is simply a matter of coughing it up. At the top there is an array called v that has a bunch of wierd number in it. Those numbers are the ranking assigned to the successfull creation of 1 in a row, 2 in a row, 3 in a row, and (altho unnecessary because it's an automatic "take it") 4 in a row for enemy first, then self. The compmove routine is called when it's the computer's turn to move. It virutally drops it's oppoenets (your) pieces in each slot, and adds up the rank of each move. Then it virtually drops it's own pieces into each slot and adds up the rank of each of those moves. Assuming that it didn't find that any move made 4 in a row (either pass), in which case it automaticly does that move, it then compares all the possible moves and chooses the highest scorer.

And as usual, I already see things I'd do to change it. Ah well, that's programming for you.

So come one, come on. Let's choose the next one. One responce with a choice, one program till we're done.
  • Battleship (like the board game vs the computer)
  • Cel Life (multi-player version of John Conway's game of Life)
  • Awari (african counting game with a learning logrithm)
  • 3DMaze (randomly generated mazes to navigate in first person perspective)
  • Pickup Piles (1000 games in one, set the rules and play)
  • Flash Cards (with pretty output, practice your math)
  • Hammurabi (rule a country, build your kingdom)
  • Black Box (find molecules in the inky depths)
  • Joust (challange the knights of the realm for the hand of the princess)
  • Hangman (guess the word before you dangle)
  • Mugwump (find the creatures hiding on a grid with a distance detector)
  • Acey Deucy (a card game of highs, lows, and middles)
  • Reverse (order a list of number by turning them around)
  • Stars/Trap/Letter Guess (3 games in 1 update, variations on a theme)
guesst is offline                         Send a private message to guesst
Reply With Quote
Old 13-06-2006, 06:56 AM   #14
Reup
10 GOSUB Abandonia
20 GOTO 10
 
Reup's Avatar

 
Join Date: Dec 2004
Location: Nuenen, Netherlands
Posts: 1,508
Default

Okay. Now do 'joust'

Btw, where you say logarithm, don't you mean algorithm?
Reup is offline                         Send a private message to Reup
Reply With Quote
Old 13-06-2006, 04:20 PM   #15
guesst
Abandonia Homie
 
guesst's Avatar

 
Join Date: May 2005
Location: Aurora, United States
Posts: 606
Default

<div class='quotetop'>QUOTE(Reup @ Jun 13 2006, 06:56 AM) [snapback]236324[/snapback]</div>
Quote:
Okay. Now do 'joust'

Btw, where you say logarithm, don't you mean algorithm?
[/b]
Ah, yes. I have a bit of a problem doing that, even in my conversation. For some reason those two words get confused in my mind. Okay, hopefully I won't do that again.

So, Joust you say, eh?
This game was another taken from a BASIC game of the same name (from the second book of BASIC programs). It's kind of a choose your own story with a weighted random. On some of the BASIC programs I converted my attempt was to duplicate the algorithm of the original game exactly, so as to experience the game as it was meant to be played. On this one, however, I couldn't resist making a few small improvements. First of all, the original game had a bug that would allow you to choose defense options that were not shown if you knew their number. Fixed. Also in this one, if you mightaly unseat your opponent your next opponent (unless it's the fearless black night) will bow out.

Buy why am I just talking about the game, I should show it to you:
Code:
/* Joust
 * Based on a BASIC game of the same name by Alan Yarbrough
 * as found in 'More BASIC Computer Games' edited by David H. Ahl (c) 1979
 * by Joseph Larson
 */

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define WAIT puts ("\nPress ENTER to continue..."); getchar(); getchar()


char *roundintro[5] = {
**"This is your first joust. You are up aginst the Red Knight."
**,"This is your second joust. Your opponent is the Silver Knight."
**,"You are doing well! Your third joust is against the Gold Knight."
**,"This is your final test! If you win this one the princess is yours!\n"
**"This fight is against the fierce Black Knight!"
**,"Huzzah! You are the winner!\n"
**"Your prowis on the field of tournament has proven you worthy of the hand\n"
**"of the princess. With the concent of her father you marry the fair maden\n"
**"and live happily ever after.\n The End."},
*aimd[8] = {"1 - Helm", "2 - Shield, Upper Left", "3 - Shield, Upper Middle"
**,"4 - Shield, Upper Right", "5 - Shield, Lower Left"
**,"6 - Shield, Lower Middle", "7 - Shield, Lower Right", "8 - Base of Shield"},
*defd[6] = {"1 - Lower Helm", "2 - Right Lean", "3 - Left Lean"
**,"4 - Steady Seat", "5 - Shield High", "6 - Shield Low"},
*defmsg[8] = {"He missed you.", "He glanced off your shield."
**,"He knocked off your helm.", "He broke his lance."
**,"He has unseated you. (Thud!)"
**,"He has broken his lance, injured and unseated you."
**,"He hs injured and useated you. (crash)"
**,"He has broken his lance and unseated you. (Clang!)"},
*aimmsg[8] = {"You missed him. (Hiss!)", "You hit his shield but glanced off." 
**,"You knocked off his helm! (Cheers!)", "You broke your lance. (Crack...)"
**,"You unseated him. (Loud cheers and huzzahs!)"
**,"You broke your lance, unseated and injured your foe. (The croud goes wild!)"
**,"You injured and unseated your opponenet."
**,"You broke your lance but unseated your opponent."};
int defok[8] = {7, 15, 63, 23, 7, 63, 7, 39},
defx[6][8] = {{0, 4, 5, 1, 3, 7, 1, 3},**{0, 3, 4, 0, 6, 1, 0, 1}, 
**{0, 0, 1, 3, 0, 3, 7, 5}, {2, 3, 3, 1, 3, 7, 1, 3}, {4, 3, 7, 1, 0, 5, 1, 5}, 
**{0, 0, 6, 4, 3, 3, 1, 3}},
aimx[8][6] = {{0, 0, 0, 2, 4, 0}, {4, 3, 0, 3, 3, 0}, {5, 4, 1, 3, 7, 6}, 
**{1, 0, 3, 1, 1, 4}, {3, 7, 1, 3, 0, 3}, {7, 1, 3, 7, 5, 3}, 
**{1, 0, 7, 1, 1, 1}, {3, 1, 4, 3, 5, 3}};

void intro (void) {
**printf ("Joust\n-----\n"
**"Hear ye, hear ye. Let all the noble knights of the kingdom come to joust\n"
**"at the King's tournament for the favor of the his daughter, the beautiful\n"
**"princess.\n\n");
}

int main (void) {
**int c, aim, def, r, droll, aroll;

**intro ();
**srand (time (NULL));
**r = 0;
**puts (roundintro[r]);
**do {
****puts ("\nChoose your aiming point :");
****for (c = 0; c < 8; c++) puts (aimd[c]);
****printf ("? "); scanf ("%d",**&aim);
****aim--;
****while (aim < 0 || aim > 7) {
******printf ("Invalid. Choose a number between 1 and 8.\n? ");
******scanf ("%d", &aim); aim--;
****}
****puts ("\nYou may use one of these defenses:");
****for (c = 0; c < 6; c++) if (defok[aim] & 1 << c) puts (defd[c]);
****printf ("? "); scanf ("%d", &def); def--;
****while (!(defok[aim] & 1 << def)) {
******printf ("Invalid. Choose an option from the menu above.\n? ");
******scanf ("%d", &def); def--;
****}
****putchar('\n');
****droll = rand () % 8;
****puts (defmsg[defx[def][droll]]);
****do {
******aroll = rand () % 6;
******switch (droll) {
********case 0:
********case 4:
********case 6: if (aroll < 3) aroll = -1; break;
********case 1: if (aroll < 2) aroll = -1; break;
********case 3: if (aroll == 0 || aroll == 2) aroll = -1; break;
********case 7: if (aroll == 1 || aroll == 2) aroll = -1;
******}
****} while (aroll < 0);
****puts (aimmsg[aimx[aim][aroll]]);
****if (defx[def][droll] < 4) 
******if (aimx[aim][aroll] > 3) {
********puts ("\nYou have won this joust.");
********r++;
********WAIT;
********puts (roundintro[r]);
********if (aimx[aim][aroll] == 5 && r < 3) {
**********puts ("\nDue to your mighty victory in the last round your next "
************"opponent has conceded \nto you the win in this round.");
**********r++;
**********WAIT;
**********puts (roundintro[r]);
********}
******}
**** else {
****** puts ("\nYou are both ready to try again.");
****** WAIT;
**** }
**} while (r < 4 && defx[def][droll] < 4);
**if (r < 4) if (aimx[aim][aroll] < 4)
****puts ("\nToo bad, you lost. You leave the field of tournament a disgrace.");
**else puts ("\nToo bad, you both lost. At least your honor is intact.");
**puts ("\nFarewell Sir Knight.");
**WAIT;
}
Sample output
Code:
Joust
-----
Hear ye, hear ye. Let all the noble knights of the kingdom come to joust
at the King's tournament for the favor of the his daughter, the beautiful
princess.

This is your first joust. You are up aginst the Red Knight.

Choose your aiming point :
1 - Helm
2 - Shield, Upper Left
3 - Shield, Upper Middle
4 - Shield, Upper Right
5 - Shield, Lower Left
6 - Shield, Lower Middle
7 - Shield, Lower Right
8 - Base of Shield
? 6

You may use one of these defenses:
1 - Lower Helm
2 - Right Lean
3 - Left Lean
4 - Steady Seat
5 - Shield High
6 - Shield Low
? 4

He broke his lance.
You broke your lance, unseated and injured your foe. (The croud goes wild!)

You have won this joust.

Press ENTER to continue...

This is your second joust. Your opponent is the Silver Knight.

Due to your mighty victory in the last round your next opponent has conceded
to you the win in this round.

Press ENTER to continue...


You are doing well! Your third joust is against the Gold Knight.

Choose your aiming point :
1 - Helm
2 - Shield, Upper Left
3 - Shield, Upper Middle
4 - Shield, Upper Right
5 - Shield, Lower Left
6 - Shield, Lower Middle
7 - Shield, Lower Right
8 - Base of Shield
? 1

You may use one of these defenses:
1 - Lower Helm
2 - Right Lean
3 - Left Lean
? 1

He glanced off your shield.
You missed him. (Hiss!)

You are both ready to try again.

Press ENTER to continue...
And so on. It is possible to win the lady, I've done it several times. But sometimes fate steps in. Try it a few times, you may like it.

Next?
  • Battleship (like the board game vs the computer)
  • Cel Life (multi-player version of John Conway's game of Life)
  • Awari (african counting game with a learning logrithm)
  • 3DMaze (randomly generated mazes to navigate in first person perspective)
  • Pickup Piles (1000 games in one, set the rules and play)
  • Flash Cards (with pretty output, practice your math)
  • Hammurabi (rule a country, build your kingdom)
  • Black Box (find molecules in the inky depths)
  • Hangman (guess the word before you dangle)
  • Mugwump (find the creatures hiding on a grid with a distance detector)
  • Acey Deucy (a card game of highs, lows, and middles)
  • Reverse (order a list of number by turning them around)
  • Stars/Trap/Letter Guess (3 games in 1 update, variations on a theme)
While at the moment this thread has Reup and Data apparently reading it, and U-Boat commander Dave offering his digits for programming skill, my hope is that this is a thread that over a long time will get noticed once in a while. But at the moment, how are you all liking it so far?
guesst is offline                         Send a private message to guesst
Reply With Quote
Old 13-06-2006, 07:10 PM   #16
Abi79
Home Sweet Abandonia

 
Join Date: May 2005
Location: Oradea, Romania
Posts: 829
Send a message via Yahoo to Abi79
Post

Quote:
But at the moment, how are you all liking it so far?[/b]
It's a very great source of C(++) games for me. Very useful, since I study C++ at school and I can use this to learn lots of things. (the next computers or how it is called olympiad will be in February, and I need to get better results then this year - I only got the 13th place out of 40 at the National Olympiad phase <_< )

And I vote for 3DMaze to be posted here next.
Abi79 is offline                         Send a private message to Abi79
Reply With Quote
Old 14-06-2006, 04:02 PM   #17
guesst
Abandonia Homie
 
guesst's Avatar

 
Join Date: May 2005
Location: Aurora, United States
Posts: 606
Default

Hey, 13 out of 40 in a competition where no morons are allowed isn't bad. You were doing well just to get in.

3DMaze
This is a real cool one. Taken from yet another entry in the International Obvscated C-Code Contest (another exelent place to find C-Code examples written by people better than me). Sean Barrett's winning 1991 entry drew an ascii representation of a first person view through a maze. For the maze the program read it's own code in and used the whitespaces for floor. Clever, but not very dynamic.

So I decided to make a random maze generator and attach it to the drawing algorithm. This meant I had to take code that was not formatted for reading and reformat it with variables with understandable names and everything. It was an interesting way to figure out how this extremely clever routine worked.

The final result is uber-cool and looks like this:
Code:
****\****************************************** /
**** |**************************************** |
**** |**************************************** |
**** |**************************************** |
**** |**************************************** |
**** |--------\********************** /--------|
**** |****** |**\****************** /**|****** |
**** |****** |****\************** /****|****** |
**** |****** |**** |************/|**** |****** |
**** |****** |**** |**********/**|**** |****** |
**** |****** |**** |---------|** |**** |****** |
**** |****** |**** |** |**** |** |**** |****** |
**** |****** |**** |---------|** |**** |****** |
**** |****** |**** |**********\**|**** |****** |
**** |****** |**** |************\|**** |****** |
**** |****** |****/************** \****|****** |
**** |****** |**/****************** \**|****** |
**** |--------/********************** \--------|
**** |**************************************** |
**** |**************************************** |
**** |**************************************** |
**** |**************************************** |
****/****************************************** \

(F)orward, (L)eft or (R)ight?
Do you want to see the program now? Here it is...
Code:
/* 3DMaze
 * by Joseph Larson 2005
 * Maze generator written by Joseph Larson
 * 3D drawing routine by Sean Barrett 1991, found at the International
 * Obfuscated C Code Contest http://www.ioccc.org
 */
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <ctype.h>
#include <string.h>
#include <math.h>

#define XMAX 39
#define YMAX 11
#define MID 26
#define WALL 0
#define UNSEEN 1
#define SEEN 2
#define TRAVL 3
#define EXIT -1
#define D(a) (2 * (a + 1))
#define NP(a, b) (a * (b - 1) + (a - 1) * b)
#define SWAP(a,b) a ^= b; b ^= a; a ^= b
#define X(a) xytable[(a) % 4]
#define Y(a) xytable[(a + 1) % 4]

int scale[6] = {11, 10, 6, 3, 1, 0};
int xytable[4] = {1, 0, -1, 0};
int maze[D(XMAX)][D(YMAX)], xsize, ysize, x, y, face, hpos;

void drawmap (void) {
**int c, d;

**for (d = 2 * ysize; d >= 0; d--) {
****putchar ('\n');
****for (c = 1; c < D(xsize); c++) 
******putchar ((c == x && d == y) ? '*' : "## ."[maze[c][d]]);
**}
}

void snr (int n1, int n2) { /* search and replace */
**int c, d;

**if (n1)
****for (c = 2; c < D(xsize); c++) for (d = 1; d < D(ysize) - 1; d++)
******if (maze[c][d] == n1) maze[c][d] = n2;
}

void generate (void) {
**int px[NP(XMAX, YMAX)], py[NP(XMAX, YMAX)], b, c, d;

**for (c = 0; c < D(XMAX); c++) for (d = 0; d < D(YMAX); d++) 
****maze[c][d] = (c) ? WALL : EXIT;
**b = 0;
**/* populate potentials */
**for (c = 3; c < 2 * xsize; c += 2) for (d = 1; d < 2 * ysize; d += 2) {
****px[b] = c; py[b++] = d;
**}
**for (c = 2; c <= 2 * xsize; c += 2) for (d = 2; d < 2 * ysize; d += 2) {
****px[b] = c; py[b++] = d;
**}
**/* randomize potentials */
**for (b = 0; b < NP(xsize, ysize); b++) {
****c = rand () % NP(xsize, ysize); 
****if (c - b) {SWAP (px[c], px[b]); SWAP (py[c], py[b]);}
**}
**/* make the maze */
**for (b = 0; b < NP(xsize, ysize); b++) {
****c = d = 0;
****if (py[b] % 2) c = 1; else d = 1;
****if (!maze[px[b] + c][py[b] + d] || !maze[px[b] - c][py[b] - d] 
******|| maze[px[b] + c][py[b] + d] != maze[px[b] - c][py[b] - d]) {
******snr (maze[px[b] + c][py[b] + d], b + 1); 
******snr (maze[px[b] - c][py[b] - d], b + 1);
******maze[px[b]][py[b]] = maze[px[b] + c][py[b] + d] 
******= maze[px[b] - c][py[b] - d] = b + 1;
****}
**}
**snr (maze[2][1], UNSEEN);
**/* now make an exit */
**maze[1][2 * (rand () % ysize) + 1] = UNSEEN;
**x =**2 * xsize; y =**2 * (rand () % ysize) + 1; face = 2;
}

int look (int f, int s) {
**int c, d, r;

**c = x + X(face) * f + X(face - 1) * s;
**d = y + Y(face) * f + Y(face - 1) * s;
**r = maze[c][d]; if (r == UNSEEN) maze[c][d] = SEEN;
**return r;
}

void draw (int col, char *s) {
**while (hpos < col) {putchar (' '); hpos++;}
**printf ("%s", s); hpos += strlen (s);
}

void draw3d(void) {
**int line, side, depth, p, q, i;
**
**putchar ('\n');
**for (line = -11; line <= 11; ++line) {
****for(side = 1, depth = 0; side + 3; side-=2) {
******for (; depth != 2 + 3 * side; depth += side) {
********if(look (depth, 0) < UNSEEN) {
**********p = scale[depth];
**********if (abs(line) < p && look(depth, 0) == WALL || abs (line) > p) break;
**********for (i = -p; i < p; ++i) draw (MID + i * 2, "--");
**********draw (0, "-"); break;
********}
********if (depth == 5) continue;
********p = scale[depth + 1]; q = scale[depth];
********if (abs (line) > q) continue;
********if (abs (line) < p) draw (MID - side * (2 * p + 1), "|");
********else if (look (depth, side)) {
**********if (abs (line) <= p)
************for(i = (side == 1 ? -q : p); i != (side == 1 ? -p : q);
**************(abs (line)), ++i)
**************draw (MID + 2 * i + (side == -1), "--");
********} else if (abs(line) == p)
**********draw (MID - side * (2 * p + 1), "|");
********else draw (MID - (abs (line) * side * 2),
**********(side == 1) ^ (line > 0) ? "\\" : "/");
******}
******depth -= side;
****}
****putchar ('\n'); hpos=0;
**}
**if (maze[x][y] != EXIT) maze[x][y] = TRAVL;
}

int move (void) {
**char in;

**printf ("\n%c (F)orward, (L)eft or (R)ight? ", "WSEN"[face]);
**do in = getche (); while (!isalnum (in)); in = tolower (in);
**if (in == 'm') drawmap ();
**else {
****if ((in == 'w' || in == 'f') && look (1, 0) != WALL)
******{x += X(face); y += Y(face);}
****if ((in == 's' || in == 'b') && look (-1, 0) != WALL)
******{x -= X(face); y -= Y(face);}
****face += (in == 'd' || in == 'r') + 3 * (in == 'a' || in == 'l');
****if (in == 'z'&& look (1, 0) != WALL) do {x += X(face); y += Y(face); draw3d ();}
******while (look (1, 0) > WALL && look (0, 1) == WALL && look (0, -1) == WALL);
****draw3d (); face %= 4;
**}
**return (in != 'q');
}

void setsize (void) {
**char in;
**
**printf ("(E)asy, (M)edium or (H)ard? ");
**do {
****do in = getche (); while (!isalnum (in)); in = tolower (in);
****switch (in) {
******case 'e' : xsize = ysize = 5; break;
******case 'm' : xsize = 15; ysize = 11; break;
******case 'h' : xsize = XMAX; ysize = YMAX; break;
******default : printf ("\nInvalad Option. Please choose E, M, or H? ");
********xsize = ysize = 0;
****}
**} while (!xsize);
}

int main (void) {
**clock_t st, et;
**double secs;
**
**srand (time (NULL));
**setsize ();
**generate ();
**draw3d ();
**st = clock ();
**while (move () && look (0,0) != EXIT);
**if (look (0, 0) == EXIT) {
****et = clock ();
****secs = (double)(et - st) / CLOCKS_PER_SEC;
****snr (UNSEEN, SEEN);
****drawmap ();
****printf ("\nYou escaped the Labryinth in %2.3f seconds!\n", secs);
**}
**exit (0);
}
I made my own keys for playing this. Yes, 'L' will go left, 'R' will go right and so forth, but also 'WADS' can be used. 'M' displays the map so far and 'Z' is a special command I made that will zip you forward until you hit a wall or a branching path.

The constants WALL, UNSEEN, SEEN, TRAVL, and EXIT are for the map. When the maze is generated you have WALLs and UNSEEN everywhere and EXIT at the end. As you see an area UNSEEN becomes SEEN and as you go there the spot you stand on becomes TRAVL. That way at the end you can see what path you took through the maze.

The maze generating algorithm doesn't make paths through the maze or anything. It just makes sure you can get anywhere from anywhere else one and only one way. It connectes two spaces with a numbered path. If two paths are connected the higher number over rides the other path so that if it wanto to join two areas it only needs to be sure they aren't of the same path, meaining a loop would be generated. A hole is punched in the left side for the exit. I had considered having a square maze, dropping the player in the exact middle, and punching one hole in any of the outside walls, meaning you could wander the wrong direction for a long time before getting out. But I decided against that for a straight east to west progression to make it less diabolical. Besides, a square map of more than 11x11 would not show well on the map printout.

This game is so cool I absolutely recomend downloading DevCPP and playing this one. It's a hoot. I wanted to include the executable here, but the boards don't allow it. But you have the code, so go on with you.

So there is 3DMaze. What's next?
  • Battleship (like the board game vs the computer)
  • Cel Life (multi-player version of John Conway's game of Life)
  • Awari (african counting game with a learning algorithm)
  • Pickup Piles (1000 games in one, set the rules and play)
  • Flash Cards (with pretty output, practice your math)
  • Hammurabi (rule a country, build your kingdom)
  • Black Box (find molecules in the inky depths)
  • Hangman (guess the word before you dangle)
  • Mugwump (find the creatures hiding on a grid with a distance detector)
  • Acey Deucy (a card game of highs, lows, and middles)
  • Reverse (order a list of number by turning them around)
  • Stars/Trap/Letter Guess (3 games in 1 update, variations on a theme)
guesst is offline                         Send a private message to guesst
Reply With Quote
Old 14-06-2006, 07:23 PM   #18
Abi79
Home Sweet Abandonia

 
Join Date: May 2005
Location: Oradea, Romania
Posts: 829
Send a message via Yahoo to Abi79
Default

Awari, Awari! (since I don't know what a learning a(?)lgorithm is, and would like to see )
Abi79 is offline                         Send a private message to Abi79
Reply With Quote
Old 14-06-2006, 08:52 PM   #19
guesst
Abandonia Homie
 
guesst's Avatar

 
Join Date: May 2005
Location: Aurora, United States
Posts: 606
Default

I don't want to post two in one day, so I'll just say (1) thanks, I missed that one. And (2) did you even play the maze game yet? Tell me what you thought of it.
guesst is offline                         Send a private message to guesst
Reply With Quote
Old 15-06-2006, 04:53 PM   #20
guesst
Abandonia Homie
 
guesst's Avatar

 
Join Date: May 2005
Location: Aurora, United States
Posts: 606
Default

Awari
Awari is an ancient African counting game. Each player has 6 places with 3 markers or stones in each to start and an empty home. A move is made by taking all the markers from any non-empty place on your side, then “sowing” the markers one at a time in a counter-clockwise direction around the board. If the last marker sown lands in your home then you get a second move. (No more than two moves in one turn.) If the last marker is sown in an empty spot and the spot opposite is not empty then you capture the last marker and all the markers in the opposite spot. When either side is empty then the game is finished.

Another conversion of a BASIC program of the same name. In the original the board was layed out left to right, more like one would play it in real life. I thought that was a bit confusing so I wrote a new version (just this morning) which layed things out top to bottom. I'm not sure it's that much better so I kept the original version but commented it out.

So here we go...
Code:
/* Awari */
/* by Joseph Larson */
/* based on a BASIC game by Geoff Wyvill */
/* as found in 'BASIC Computer Games' edited by David H. Ahl (c) 1978 */

#include <stdio.h>
#include <time.h>
#include <math.h>

int memory[51], board[14];
int turn;

void intro (void) {
**char input;

**printf ("\nAwari\n");
**printf ("------\n");
**printf ("Do you need the rules? (y\\n) ");
**scanf ("%c", &input);
**if ((input == 'y') || (input == 'Y')) {
****printf ("\nAwari is an ancient African counting game. Each player has 6\n"
****"places with 3 markers or stones in each to start and an empty home. A\n"
****"move is made by taking all the markers from any non-empty place on your\n"
****"side, then \"sowing\" the markers one at a time in a counter-clockwise\n"
****"direction around the board. If the last marker sown lands in your home\n"
****"then you get a second move. (No more than two moves in one turn.)\n\n"
****"If the last marker is sown in an empty spot and the spot opposite is not\n"
****"empty then you capture the last marker and all the markers in the\n"
****"opposite spot. When either side is empty then the game is finished.\n\n"
****"Player one is at the left with home at the bottom, player two (or the\n"
****"computer in a one player game) is at the right with home at the top.\n"
****"By the way, the computer opponent is designed so that the more you play\n"
****"it, the better it gets.\n\n"
****"Good luck and have fun!\n");
**}
}

void drawboard (void) {
**int c;
**
**printf("\n\t (%2d)**Player 2", board[13]);
**for (c = 0; c < 6; c++)
****printf ("\n\n %d (%2d)\t\t(%2d) %d", c + 1, board[c], board[12 - c], 6 - c);
**printf("\n\nPlayer 1**(%2d)\n\n", board[6]);
/***printf ("\n");
**for (c = 12; c > 6; c--) printf ("%3d ", board[c]);
**printf ("\n%d %24d \n", board[13], board[6]);
**for (c = 0; c < 6; c++) printf ("%3d ", board[c]);
**printf ("\n\n"); */
}

int domove (int move, int home) {
**int c;

**c = board[move]; board[move] = 0;
**do {
****if (++move > 13) move -= 14;
****board[move]++;
**} while (--c > 0);
**if ((board[move] == 1) && (move != 6) && (move !=13) && (board[12 - move])) {
****board[home] += board[12 - move] + 1;
****board[move] = board[12 - move] = 0;
**}
**if (move == home) return (1);
**else return (0);
}

void remember (int move) {
**turn++;
**if (move > 6) move -= 7;
**if (turn < 9) memory[memory[0]] = memory[memory[0]] * 6 + move;
}

int playermove (int pl) {
**int input;

**do {
****printf ("Player #%d, your move? (1 - 6) ", pl + 1);
****scanf ("%d", &input);
****if ((input < 1) || (input > 6) || !board[input + ((pl) ? 6 : - 1)]) {
******printf ("Illegal move.\n");
******input=0;
****}
**} while (!input);
**remember (--input);
**return (input + ((pl) ? 7 : 0));
}

int computermove (void) {
**int move, bestmove, rank, bestrank, c, r, check;
**int saveboard[14];
**
**for (c=0; c < 14; c++) saveboard[c] = board[c];
**bestrank = -99;
**for (move = 7; move <= 12; move++)
****if (board[move]) {
******rank = 0;
******domove(move, 13);
******for (c = 0; c < 5; c++)
********if (board[c]) {
**********r = 0; check = board[c] + c;
**********while (check > 14) { check -= 14; r = -1;}
**********if ((!board[check]) && (check !=6) && (check != 13))
**********r-=board[12 - check]; rank =(r < rank) ?**r : rank;
********}
******rank += board[13] - board[6];
******if (turn < 9) {
********check = memory[memory[0]] * 6 + move - 7;
********for (c = 1; c < memory[0]; c++)
**********if ( check == (int) ((float) memory[c] / pow (6, (7 - turn)) + 0.1))
************rank -= 2;
******}
******for (c=0; c < 14; c++) board[c] = saveboard[c];
******if (rank >= bestrank) {bestrank = rank; bestmove**= move;}
****}
**remember (bestmove);
**printf("Computer moves %d", (bestmove - 6));
**return (bestmove);
}

int endgame (void) {
**int c, d, e;

**d = e = 0;
**for (c = 0; c < 6; c++) d += board[c];
**for (c = 7; c < 13; c++) e += board[c];
**if ((!d) || (!e)) return (1);
**else return (0);
}

void playgame (void) {
**int c, numpl;

**for (c = 0; c < 13; c++) board[c] = 3;
**board[6] = board [13] = memory[memory[0]] = numpl = 0;
**do {
****printf ("\nHow many players (1 - 2) ? ");
****scanf ("%d", &numpl);
****if (numpl < 1 || numpl > 2) {
******printf ("Please input either 1 or 2.\n");
******numpl = 0;
****}
**} while (!numpl);
**turn = 0;
**do {
****drawboard ();
****if (domove (playermove (0), 6))
******if (!endgame()) {
********drawboard ();
********printf ("Again.\n");
********domove (playermove (0), 6);
******}
****drawboard ();
****if**(!endgame ()) {
******if (domove ((numpl - 1) ? playermove (1) : computermove (), 13))
********if (!endgame()) {
**********drawboard ();
**********printf ("Again.\n");
**********domove ((numpl - 1) ? playermove (1) : computermove (), 13);
********}
******printf("\n");
****}
**} while (!endgame ());
**drawboard ();
**printf ("\nGame Over.\n");
**c = board[6]-board[13];
**if (c < 0) printf ("%s by %d points.\n", 
**(numpl - 1) ? "Player 2 wins" : "I win", (-c));
****else {
******if (numpl - 1 && memory[0] < 50) memory[0]++;
******if (c == 0) printf ("Drawn game.\n");
******else printf ("Player 1 wins by %d points.\n", c);
****}
}

int playagain (void) {
**char input[50];

**printf ("\nDo you want to play again? (y\\n) ");
**scanf ("%s", input);
**if ((input[0] == 'y') || (input[0] == 'Y')) return 1;
**else return 0;
}

void loadmemory (void) {
**FILE *fp;
**int c;
**
**c = 0;
**fp = fopen ("awari.dat", "r");
**if (fp == NULL)
****memory[0] = 1;
**else {
****while (!feof (fp)) fscanf (fp, "%d", &memory[c++]);
****fclose (fp);
**}
}

void savememory (void) {
**FILE *fp;
**int c;
**
**fp = fopen ("awari.dat", "w");
**if (fp != NULL) {
****for (c=0; c <= memory[0]; c++)
******fprintf(fp, "%d\n", memory[c]);
****fclose(fp);
**}
}

int main (void) {
**intro ();
**loadmemory ();
**do playgame (); while (playagain ());
**if (memory[0] > 1) savememory ();
**return 0;
}
The AI plays by a fairly simple set of rules; Try every move and see which one scores the most point with provision for if you leave yourself open, but then takes it a step further. Every game is encoded into a number that if looked at in base 6 (not one of your common bases) is the first 8 digits of the game played. Then every game so far is compared to an array of games that it lost in the past. If this game is shaping up to look like a loser it will adjust it's strategy. In other words, when the computer loses it tucks that loss away and tries not to make that mistake again.

The list gets shorter every time! This time I added one I had forgotten however.
  • Battleship (like the board game vs the computer)
  • Cel Life (multi-player version of John Conway's game of Life)
  • Pickup Piles (1000 games in one, set the rules and play)
  • Flash Cards (with pretty output, practice your math)
  • Hammurabi (rule a country, build your kingdom)
  • Black Box (find molecules in the inky depths)
  • Hangman (guess the word before you dangle)
  • Rotate (like those sliding block puzzles but that you rotate pieces)
  • Mugwump (find the creatures hiding on a grid with a distance detector)
  • Acey Deucy (a card game of highs, lows, and middles)
  • Reverse (order a list of number by turning them around)
  • Stars/Trap/Letter Guess (3 games in 1 update, variations on a theme)
guesst is offline                         Send a private message to guesst
Reply With Quote
Reply


Similar Threads
Thread Thread Starter Forum Replies Last Post
Happy Birthday Guesst Japo Birthdays & Celebrations 8 06-07-2007 09:50 AM
Happy Birthday, Guesst Shrek Blah, blah, blah... 10 08-07-2006 09:31 AM

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump
 


The current time is 02:47 PM (GMT)

 
Powered by vBulletin® Version 3.7.1
Copyright ©2000 - 2019, Jelsoft Enterprises Ltd.