980 lines
15 KiB
C
980 lines
15 KiB
C
/* robots.c
|
|
|
|
A turn-based game for CP/M-80 & CP/M-86.
|
|
|
|
Based on ROBOTS, a BSD game (but no source code was taken from it).
|
|
|
|
The objetive of the robots is only one: to kill you.
|
|
|
|
The only thing you can do, is to try to escape from them. But use the
|
|
teletransportation with care: you have only a few teletransport tickets!
|
|
|
|
The robots will die if they collide between them or crash against something.
|
|
|
|
That's your only opportunity to win the robots.
|
|
|
|
Good luck!
|
|
|
|
Copyright (c) 2015 Miguel I. Garcia Lopez / FloppySoftware.
|
|
|
|
A VT100 clear screen control code has been added by Anna Christina Naß <acn@acn.wtf>
|
|
|
|
This program is free software; you can redistribute it and/or modify it
|
|
under the terms of the GNU General Public License as published by the
|
|
Free Software Foundation; either version 2, or (at your option) any
|
|
later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
|
|
Contact:
|
|
|
|
www.floppysoftware.vacau.com
|
|
cpm-connections.blogspot.com
|
|
floppysoftware@gmail.com
|
|
|
|
Usage:
|
|
|
|
robots
|
|
|
|
Compile with MESCC (CP/M-80):
|
|
|
|
cc robots
|
|
zsm robots
|
|
hextocom robots
|
|
|
|
Compile with DR-C (CP/M-86):
|
|
|
|
drc robots
|
|
link86 robots
|
|
|
|
Compile with MESCC (SamaruX):
|
|
|
|
cc robots
|
|
zmac robots.zsm --rel
|
|
link robots [op]
|
|
rename robots.x=robots.prl
|
|
|
|
Changes:
|
|
|
|
18 Mar 2015 : 0.01 : Initial work from TinyWar source code.
|
|
19 Mar 2015 : 1.00 : 1st version.
|
|
09 Apr 2015 : 1.01 : Added support for SamaruX.
|
|
*/
|
|
|
|
/* TARGET: uncomment only one of following lines
|
|
---------------------------------------------
|
|
*/
|
|
|
|
#define CPM80
|
|
/* #define CPM86 */
|
|
/* #define SAMARUX */
|
|
|
|
/* MESCC LIBRARIES
|
|
---------------
|
|
*/
|
|
|
|
#ifdef CPM80
|
|
|
|
#define CC_NO_ARGS
|
|
|
|
#include "mescc.h"
|
|
#include "conio.h"
|
|
#include "ctype.h"
|
|
#include "string.h"
|
|
#include "printf.h"
|
|
|
|
#endif
|
|
|
|
/* SAMARUX LIBRARIES
|
|
-----------------
|
|
*/
|
|
|
|
#ifdef SAMARUX
|
|
|
|
#include "samarux.h"
|
|
|
|
#endif
|
|
|
|
/* DR-C LIBRARIES & SUPPORT STUFF
|
|
------------------------------
|
|
*/
|
|
|
|
#ifdef CPM86
|
|
|
|
#include "stdio.h"
|
|
|
|
#undef getchar
|
|
|
|
/* DR-C doesn't have this one */
|
|
|
|
kbhit()
|
|
{
|
|
return __BDOS(11, 0);
|
|
}
|
|
|
|
/* DR-C doesn't work well mixing getchar() from STDIO.H
|
|
and our kbhit() */
|
|
|
|
getchar()
|
|
{
|
|
return __BDOS(1, 0);
|
|
}
|
|
|
|
/* DR-C doesn't have this one */
|
|
|
|
putstr(s)
|
|
char *s;
|
|
{
|
|
while(*s)
|
|
putchar(*s++);
|
|
}
|
|
|
|
/* DR-C has this one as a macro in CTYPE.H but cause
|
|
some problems with this code */
|
|
|
|
toupper(ch)
|
|
int ch;
|
|
{
|
|
if(ch >= 'a' && ch <= 'z')
|
|
ch -= 32;
|
|
|
|
return ch;
|
|
}
|
|
|
|
#endif
|
|
|
|
/* CLEAR SCREEN
|
|
------------
|
|
*/
|
|
|
|
ClrScr()
|
|
{
|
|
printf("%c[2J%c[H", 27, 27);
|
|
}
|
|
|
|
/* GAME DEFs & GLOBALS
|
|
-------------------
|
|
*/
|
|
|
|
#define BOARD_ROWS 16 /* Board rows */
|
|
#define BOARD_COLS 16 /* Board columns */
|
|
#define BOARD_SIZE 256 /* Board cells = BOARD_ROWS * BOARD_COLS */
|
|
|
|
int brd_rows[BOARD_ROWS]; /* Board rows - char *brd_rows[] */
|
|
char brd_cell[BOARD_SIZE]; /* Board cells */
|
|
|
|
#define ROBOTS_UNITS 8 /* # of robots */
|
|
|
|
int robots_left; /* Robots left in board */
|
|
|
|
int human_life; /* NZ if human is alive */
|
|
int human_row; /* Row position */
|
|
int human_col; /* Column position */
|
|
|
|
#define TELETR_UNITS 3 /* Teletransportation units */
|
|
|
|
int teltr_left; /* Teletransportation units left */
|
|
|
|
int moves; /* Number of moves done */
|
|
|
|
int random; /* Random number from 0 to 32767, managed by KbdIn() */
|
|
|
|
int running; /* NZ if we are playing, Z to quit */
|
|
|
|
int act_robots; /* NZ if robots can play */
|
|
|
|
char *brd_msg; /* Pointer to board message */
|
|
|
|
/* BOARD OBJECTS
|
|
-------------
|
|
*/
|
|
|
|
#define TYPE_GROUND ' '
|
|
#define TYPE_WALL 'X'
|
|
#define TYPE_ROBOT 'R'
|
|
#define TYPE_HUMAN 'H'
|
|
#define TYPE_DEAD 'D'
|
|
#define TYPE_SCRAP 'C'
|
|
#define TYPE_TEMP 'T'
|
|
|
|
/* SPRITES
|
|
-------
|
|
*/
|
|
|
|
#define SPR_GROUND " "
|
|
#define SPR_WALL "@@@"
|
|
#define SPR_HUMAN ".P."
|
|
#define SPR_DEAD "XPX"
|
|
#define SPR_SCRAP "X'X"
|
|
|
|
#define SPR_ROBOT0 "/'\\"
|
|
#define SPR_ROBOT1 "/'|"
|
|
#define SPR_ROBOT2 "|'\\"
|
|
#define SPR_ROBOT3 "|'|"
|
|
|
|
/* KEYS
|
|
----
|
|
*/
|
|
|
|
#define K_UP '8'
|
|
#define K_DOWN '2'
|
|
#define K_LEFT '4'
|
|
#define K_RIGHT '6'
|
|
#define K_UP_LEFT '7'
|
|
#define K_UP_RIGHT '9'
|
|
#define K_DOWN_LEFT '1'
|
|
#define K_DOWN_RIGHT '3'
|
|
#define K_TELETRANSP 'T'
|
|
#define K_STOP 'Q'
|
|
|
|
|
|
/* MAIN CODE
|
|
---------
|
|
*/
|
|
|
|
main()
|
|
{
|
|
ClrScr();
|
|
|
|
/* Show the banner, copyright info, etc. */
|
|
|
|
Banner();
|
|
|
|
/* Set up the board */
|
|
|
|
SetUpBoard();
|
|
|
|
/* Clean the board */
|
|
|
|
SetBoard();
|
|
|
|
/* We are playing! */
|
|
|
|
running = 1;
|
|
|
|
/* Main loop */
|
|
|
|
while(human_life && robots_left && running)
|
|
{
|
|
ClrScr();
|
|
|
|
/* Show the board */
|
|
|
|
PrtLn();
|
|
PrtBoard();
|
|
PrtLn();
|
|
|
|
/* Robots should do their part */
|
|
|
|
act_robots = 1;
|
|
|
|
/* Ask human for an action */
|
|
|
|
AskAction();
|
|
|
|
/* Robots should play too? */
|
|
|
|
if(act_robots)
|
|
ActRobots();
|
|
}
|
|
|
|
/* Game is over, check the reason and print a message */
|
|
|
|
if(!human_life)
|
|
Msg("You are dead, bad luck!");
|
|
else if(!robots_left)
|
|
Msg("You win, congratulations!");
|
|
else
|
|
Msg("Ok, I'm leaving! See you!");
|
|
|
|
/* Show the board for last time */
|
|
|
|
ClrScr();
|
|
PrtLn();
|
|
PrtBoard();
|
|
}
|
|
|
|
/* BANNER, COPYRIGHT, ETC.
|
|
-----------------------
|
|
*/
|
|
|
|
Banner()
|
|
{
|
|
/* Good looking banner */
|
|
|
|
puts("\n R () : : ()");
|
|
puts(" R O B O T S \\ [0_0] /");
|
|
puts(" B x-+-:-+-x");
|
|
puts("R O B O T S |___|");
|
|
puts(" T / \\");
|
|
puts(" S \\ / v1.00\n");
|
|
|
|
/* Copyright and contact details */
|
|
|
|
puts("(c) 2015 Miguel Garcia / FloppySoftware");
|
|
puts("www.floppysoftware.vacau.com");
|
|
puts("cpm-connections.blogspot.com");
|
|
puts("floppysoftware@gmail.com\n");
|
|
|
|
/* Waiting for the user */
|
|
|
|
putstr("Press any key to start... ");
|
|
|
|
/* Wait a keyboard entry (this will be useful for random number generation) */
|
|
|
|
KbdIn();
|
|
|
|
/* New line */
|
|
|
|
PrtLn();
|
|
}
|
|
|
|
/* HUMAN ACTION
|
|
------------
|
|
*/
|
|
|
|
AskAction()
|
|
{
|
|
int action;
|
|
|
|
/* No board message */
|
|
|
|
Msg(NULL);
|
|
|
|
/* Ask for action */
|
|
|
|
putstr("Action? ");
|
|
|
|
/* Read keyboard */
|
|
|
|
action = KbdIn();
|
|
|
|
if(action != '\n')
|
|
PrtLn();
|
|
|
|
/* Do the action */
|
|
|
|
switch(action)
|
|
{
|
|
case K_UP :
|
|
ActMove(-1, 0);
|
|
break;
|
|
case K_DOWN :
|
|
ActMove(1, 0);
|
|
break;
|
|
case K_LEFT :
|
|
ActMove(0, -1);
|
|
break;
|
|
case K_RIGHT :
|
|
ActMove(0, 1);
|
|
break;
|
|
case K_UP_LEFT :
|
|
ActMove(-1, -1);
|
|
break;
|
|
case K_UP_RIGHT :
|
|
ActMove(-1, 1);
|
|
break;
|
|
case K_DOWN_LEFT :
|
|
ActMove(1, -1);
|
|
break;
|
|
case K_DOWN_RIGHT :
|
|
ActMove(1, 1);
|
|
break;
|
|
|
|
case K_TELETRANSP :
|
|
ActTelTr();
|
|
break;
|
|
|
|
case K_STOP :
|
|
ActExit();
|
|
break;
|
|
|
|
default :
|
|
act_robots = 0;
|
|
break;
|
|
}
|
|
}
|
|
|
|
/* ASK HUMAN FOR CONFIRMATION
|
|
--------------------------
|
|
*/
|
|
|
|
AskConfirm()
|
|
{
|
|
int reply;
|
|
|
|
/* Prompt */
|
|
|
|
putstr("Confirm (Yes, No)? ");
|
|
|
|
/* Read keyboard */
|
|
|
|
reply = KbdIn();
|
|
|
|
if(reply != '\n')
|
|
PrtLn();
|
|
|
|
/* Return TRUE or FALSE */
|
|
|
|
return reply == 'Y' ? 1 : 0;
|
|
}
|
|
|
|
/* MOVE THE HUMAN
|
|
--------------
|
|
*/
|
|
|
|
ActMove(srow, scol)
|
|
int srow, scol;
|
|
{
|
|
int to_row, to_col, type;
|
|
|
|
/* To where? */
|
|
|
|
to_row = human_row + srow;
|
|
to_col = human_col + scol;
|
|
|
|
/* Act if next position is inside of board */
|
|
|
|
if(to_row >= 0 && to_row < BOARD_ROWS && to_col >= 0 && to_col < BOARD_COLS)
|
|
{
|
|
/* Check contents of new position */
|
|
|
|
type = GetCell(to_row, to_col);
|
|
|
|
if(type == TYPE_GROUND)
|
|
{
|
|
/* GROUND: move human there */
|
|
|
|
SetCell(human_row, human_col, TYPE_GROUND);
|
|
|
|
human_row = to_row;
|
|
human_col = to_col;
|
|
|
|
SetCell(human_row, human_col, TYPE_HUMAN);
|
|
|
|
/* Increment moves */
|
|
|
|
++moves;
|
|
|
|
/* Done */
|
|
|
|
return;
|
|
}
|
|
else if(type == TYPE_ROBOT)
|
|
{
|
|
/* ROBOT: human is dead */
|
|
|
|
--human_life;
|
|
|
|
SetCell(human_row, human_col, TYPE_DEAD);
|
|
}
|
|
}
|
|
|
|
/* Robots will do nothing */
|
|
|
|
act_robots = 0;
|
|
}
|
|
|
|
/* TELETRANSPORTATION
|
|
------------------
|
|
*/
|
|
|
|
ActTelTr()
|
|
{
|
|
int to_row, to_col;
|
|
|
|
/* Do it if there are some teletransportations units */
|
|
|
|
if(teltr_left)
|
|
{
|
|
/* Find a random safe location */
|
|
|
|
do {
|
|
|
|
to_row = random % BOARD_ROWS;
|
|
to_col = random % BOARD_COLS;
|
|
|
|
random += 3;
|
|
|
|
} while(GetCell(to_row, to_col) != TYPE_GROUND);
|
|
|
|
/* Move the human there */
|
|
|
|
SetCell(human_row, human_col, TYPE_GROUND);
|
|
|
|
human_row = to_row;
|
|
human_col = to_col;
|
|
|
|
SetCell(human_row, human_col, TYPE_HUMAN);
|
|
|
|
/* We lost a teletransportation unit */
|
|
|
|
--teltr_left;
|
|
|
|
/* Increment moves */
|
|
|
|
++moves;
|
|
}
|
|
|
|
/* Robots will do nothing */
|
|
|
|
act_robots = 0;
|
|
}
|
|
|
|
/* QUIT GAME
|
|
---------
|
|
*/
|
|
|
|
ActExit()
|
|
{
|
|
/* Ask for confirmation */
|
|
|
|
PrtLn();
|
|
|
|
running = !AskConfirm();
|
|
|
|
/* Robots will do nothing */
|
|
|
|
act_robots = 0;
|
|
}
|
|
|
|
|
|
/* MOVE ROBOTS
|
|
-----------
|
|
*/
|
|
|
|
ActRobots()
|
|
{
|
|
int row, col, to_row, to_col, type;
|
|
|
|
/* Search robots in the board */
|
|
|
|
for(row = 0; row < BOARD_ROWS; ++row)
|
|
{
|
|
for(col = 0; col < BOARD_COLS; ++col)
|
|
{
|
|
/* Cell has a robot? */
|
|
|
|
if(GetCell(row, col) == TYPE_ROBOT)
|
|
{
|
|
/* Move near to the human */
|
|
|
|
to_row = row;
|
|
to_col = col;
|
|
|
|
|
|
/* Look for new row position */
|
|
|
|
if(row < human_row)
|
|
++to_row;
|
|
else if(row > human_row)
|
|
--to_row;
|
|
|
|
/* Look for new column position */
|
|
|
|
if(col < human_col)
|
|
++to_col;
|
|
else if(col > human_col)
|
|
--to_col;
|
|
|
|
/* Is there something there? */
|
|
|
|
type = GetCell(to_row, to_col);
|
|
|
|
if(type == TYPE_GROUND)
|
|
{
|
|
/* GROUND: Move the robot there */
|
|
|
|
SetCell(row, col, TYPE_GROUND);
|
|
SetCell(to_row, to_col, TYPE_TEMP);
|
|
}
|
|
else
|
|
{
|
|
/* NOT GROUND: Robot is dead */
|
|
|
|
SetCell(row, col, TYPE_SCRAP);
|
|
|
|
/* This robot is dead */
|
|
|
|
--robots_left;
|
|
|
|
/* If there is the human or another robot
|
|
there, he is dead too */
|
|
|
|
if(type == TYPE_ROBOT || type == TYPE_TEMP)
|
|
{
|
|
/* Robot: dead */
|
|
|
|
SetCell(to_row, to_col, TYPE_SCRAP);
|
|
|
|
--robots_left;
|
|
}
|
|
else if(type == TYPE_HUMAN)
|
|
{
|
|
/* Human: dead */
|
|
|
|
SetCell(to_row, to_col, TYPE_DEAD);
|
|
|
|
--human_life;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Persist the new locations of the robots */
|
|
|
|
for(row = 0; row < BOARD_ROWS; ++row)
|
|
{
|
|
for(col = 0; col < BOARD_COLS; ++col)
|
|
{
|
|
if(GetCell(row, col) == TYPE_TEMP)
|
|
SetCell(row, col, TYPE_ROBOT);
|
|
}
|
|
}
|
|
}
|
|
|
|
/* SHOW THE BOARD
|
|
--------------
|
|
*/
|
|
|
|
PrtBoard()
|
|
{
|
|
int i, row, col, type;
|
|
|
|
PrtBoardLn();
|
|
|
|
for(row = 0; row < BOARD_ROWS; ++row)
|
|
{
|
|
/* Left panel */
|
|
|
|
putchar('|');
|
|
|
|
for(col = 0; col < BOARD_COLS; ++col)
|
|
{
|
|
/* Get cell contents */
|
|
|
|
type = GetCell(row, col);
|
|
|
|
/* Act according to the cell contents */
|
|
|
|
switch(type)
|
|
{
|
|
case TYPE_GROUND :
|
|
putstr(SPR_GROUND);
|
|
break;
|
|
|
|
case TYPE_ROBOT :
|
|
switch(row & 0x03)
|
|
{
|
|
case 0 : putstr(SPR_ROBOT0); break;
|
|
case 1 : putstr(SPR_ROBOT1); break;
|
|
case 2 : putstr(SPR_ROBOT2); break;
|
|
case 3 : putstr(SPR_ROBOT3); break;
|
|
}
|
|
break;
|
|
|
|
case TYPE_SCRAP :
|
|
putstr(SPR_SCRAP);
|
|
break;
|
|
|
|
case TYPE_HUMAN :
|
|
putstr(SPR_HUMAN);
|
|
break;
|
|
|
|
case TYPE_DEAD :
|
|
putstr(SPR_DEAD);
|
|
break;
|
|
|
|
case TYPE_WALL :
|
|
putstr(SPR_WALL);
|
|
break;
|
|
}
|
|
}
|
|
|
|
/* Right panel */
|
|
|
|
putchar('|');
|
|
|
|
switch(row)
|
|
{
|
|
case 1 :
|
|
putstr(" 7 8 9 ");
|
|
break;
|
|
case 2 :
|
|
putstr(" \\|/ ");
|
|
break;
|
|
case 3 :
|
|
putstr(" 4 --+-- 6 ");
|
|
break;
|
|
case 4 :
|
|
putstr(" /|\\ ");
|
|
break;
|
|
case 5 :
|
|
putstr(" 1 2 3 ");
|
|
break;
|
|
|
|
case 7 :
|
|
putstr(" T:Teletran. ");
|
|
break;
|
|
case 8 :
|
|
putstr(" Q:Quit ");
|
|
break;
|
|
|
|
case 12:
|
|
printf(" Teletr.: %2d ", teltr_left);
|
|
break;
|
|
case 13:
|
|
printf(" Moves: %4d ", moves);
|
|
break;
|
|
|
|
case 10:
|
|
putstr("-------------");
|
|
break;
|
|
|
|
default :
|
|
putstr(" "); break;
|
|
}
|
|
|
|
putchar('|');
|
|
|
|
PrtLn();
|
|
}
|
|
|
|
PrtBoardLn();
|
|
|
|
/* Show message */
|
|
|
|
putstr("| ");
|
|
|
|
putstr(brd_msg);
|
|
|
|
for(i = 3 * BOARD_COLS - strlen(brd_msg) - 1; i; --i)
|
|
putchar(' ');
|
|
|
|
puts("| R O B O T S |");
|
|
|
|
PrtBoardLn();
|
|
}
|
|
|
|
/* PRINT BOARD LINE
|
|
----------------
|
|
*/
|
|
|
|
PrtBoardLn()
|
|
{
|
|
int col;
|
|
|
|
putchar('+');
|
|
|
|
for(col = 0; col < BOARD_COLS; ++col)
|
|
putstr("---");
|
|
|
|
puts("+-------------+");
|
|
}
|
|
|
|
/* PRINT NEW LINE
|
|
--------------
|
|
*/
|
|
|
|
PrtLn()
|
|
{
|
|
putchar('\n');
|
|
}
|
|
|
|
/* SET UP BOARD
|
|
------------
|
|
*/
|
|
|
|
SetUpBoard()
|
|
{
|
|
int i;
|
|
|
|
/* Set up the rows pointers */
|
|
|
|
for(i = 0; i < BOARD_ROWS; ++i)
|
|
brd_rows[i] = brd_cell + i * BOARD_COLS;
|
|
}
|
|
|
|
/* CLEAR THE BOARD
|
|
---------------
|
|
*/
|
|
|
|
ClearBoard()
|
|
{
|
|
int row, col;
|
|
|
|
/* Clear all cells */
|
|
|
|
for(row = 0; row < BOARD_ROWS; ++row)
|
|
for(col = 0; col < BOARD_COLS; ++col)
|
|
SetCell(row, col, TYPE_GROUND);
|
|
}
|
|
|
|
/* SET CELL CONTENTS
|
|
-----------------
|
|
*/
|
|
|
|
SetCell(row, col, type)
|
|
int row, col, type;
|
|
{
|
|
char *p;
|
|
|
|
/* Get the row pointer */
|
|
|
|
p = brd_rows[row];
|
|
|
|
/* Set the cell value */
|
|
|
|
p[col] = type;
|
|
}
|
|
|
|
/* GET CELL CONTENTS
|
|
-----------------
|
|
*/
|
|
|
|
GetCell(row, col)
|
|
int row, col;
|
|
{
|
|
char *p;
|
|
|
|
/* Get the row pointer */
|
|
|
|
p = brd_rows[row];
|
|
|
|
/* Set the cell value */
|
|
|
|
return p[col];
|
|
}
|
|
|
|
/* SET BOARD MESSAGE
|
|
-----------------
|
|
*/
|
|
|
|
Msg(txt)
|
|
char *txt;
|
|
{
|
|
brd_msg = txt == NULL ? "(c) 2015 FloppySoftware" : txt;
|
|
}
|
|
|
|
/* SET BOARD CONTENTS
|
|
------------------
|
|
*/
|
|
|
|
SetBoard()
|
|
{
|
|
int row, col, i, x;
|
|
char *pos;
|
|
|
|
/* Clear message */
|
|
|
|
Msg(NULL);
|
|
|
|
/* Clear board */
|
|
|
|
ClearBoard();
|
|
|
|
/* Reset some values */
|
|
|
|
moves = 0;
|
|
teltr_left = TELETR_UNITS;
|
|
|
|
/* Set some walls */
|
|
|
|
SetCell(2, 2, TYPE_WALL);
|
|
SetCell(3, 2, TYPE_WALL);
|
|
SetCell(BOARD_ROWS - 4, BOARD_COLS - 3, TYPE_WALL);
|
|
SetCell(BOARD_ROWS - 3, BOARD_COLS - 3, TYPE_WALL);
|
|
|
|
/* Set human values */
|
|
|
|
human_life = 1;
|
|
|
|
human_row = BOARD_ROWS / 2;
|
|
human_col = BOARD_COLS / 2;
|
|
|
|
SetCell(human_row, human_col, TYPE_HUMAN);
|
|
|
|
/* Set robots values */
|
|
|
|
robots_left = ROBOTS_UNITS;
|
|
|
|
/* Locate robots in random positions */
|
|
|
|
/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
|
|
pos = "044E8AF2C5638EB229E936FAE5471EBB";
|
|
|
|
/* Get a number from 0 to 31 */
|
|
|
|
x = random % 32;
|
|
|
|
i = 0;
|
|
|
|
while(i < robots_left)
|
|
{
|
|
/* Get a position */
|
|
|
|
row = GetVal(pos[x++]) % BOARD_ROWS; if(x > 31) x = 0;
|
|
col = GetVal(pos[x++]) % BOARD_COLS; if(x > 31) x = 0;
|
|
|
|
/* Place the robot there, if the location is empty */
|
|
|
|
if(GetCell(row, col) == TYPE_GROUND)
|
|
{
|
|
SetCell(row, col, TYPE_ROBOT);
|
|
|
|
++i;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* HELPER FOR SetBoard()
|
|
---------------------
|
|
*/
|
|
|
|
GetVal(c)
|
|
int c;
|
|
{
|
|
/* Return HEX value of digit */
|
|
|
|
if(c >= '0' && c <= '9')
|
|
return c - '0';
|
|
|
|
return c - 'A' + 10;
|
|
}
|
|
|
|
/* GET CHARACTER FROM KEYBOARD AND SET RANDOM VALUE
|
|
------------------------------------------------
|
|
*/
|
|
|
|
KbdIn()
|
|
{
|
|
/* Init random value */
|
|
|
|
random = 0;
|
|
|
|
/* Wait for a key and increment the random value */
|
|
|
|
while(!kbhit())
|
|
++random;
|
|
|
|
/* Set the random value to a legal one (0 ... 32767) */
|
|
|
|
random &= 0x7FFF;
|
|
|
|
/* Return character */
|
|
|
|
return toupper(getchar());
|
|
}
|
|
|
|
|
|
|
|
|