More BefunGen desc
This commit is contained in:
parent
14f3d5df3b
commit
03e0ae3214
@ -0,0 +1,37 @@
|
||||
In TextFunge you can optionally define a read- and writable display area.
|
||||
|
||||
```textfunge
|
||||
program example_01 : display[16, 16]
|
||||
```
|
||||
|
||||
The display has a width and a height and every field has initially the value you set in the options (the standard is space).
|
||||
|
||||
You can access the display with the `display[x, y]` command.
|
||||
|
||||
```textfunge
|
||||
display[0, 0] = 'X'; // Write 'X' to position (0,0)
|
||||
c = display[0, 1]; // Set c to the value of (0,1)
|
||||
```
|
||||
|
||||
There are also a few automatically defined constants for teh work with displays:
|
||||
|
||||
```textfunge
|
||||
DISPLAY_WIDTH // The width of the display
|
||||
DISPLAY_HEIGHT // The height of the display
|
||||
DISPLAY_SIZE // The size (width*height) of the display
|
||||
```
|
||||
|
||||
You can use the display to
|
||||
|
||||
- display information to the user without using input commands
|
||||
- gather a big amount of data from the user before execution (he has to fill the display manually)
|
||||
- use it as a big 2-dimensional array for calculations
|
||||
|
||||
> **Note:**
|
||||
> Beware that there is normally no mechanism to control access overflow.
|
||||
> So you can enter to high/low x/y values and access/modify program pieces that are not part of the display.
|
||||
> This is a way of bricking your program by writing in the area of program code
|
||||
>
|
||||
>**Tip:**
|
||||
> You can prevent this by enabling the compiler option *Prevent display overflow*.
|
||||
> But beware that tis will result in longer display access times.
|
@ -0,0 +1,37 @@
|
||||
There are a few things you should consider when creating programs with Befunge:
|
||||
|
||||
###Number ranges
|
||||
|
||||
The size of the internal numbers is dependent on the interpreter, while you can safely assume that the number is at least 16bit, everything higher is not sure.
|
||||
So for bigger programs you have to either work with smaller numbers or use interpreters which use bigger sizes.
|
||||
|
||||
> **Tip:**
|
||||
> [BefunExec](/programs/view/BefunGen) uses 64bit integer (= long values).
|
||||
|
||||
###Negative numbers
|
||||
|
||||
A real problem are negative numbers. In created programs variables are saved in the grid.
|
||||
If the interpreter does not support negative grid values you will not be able to use negative numbers.
|
||||
|
||||
But don't worry too much - most interpreters I know support negative numbers in the grid.
|
||||
|
||||
###Performance
|
||||
|
||||
BefunGen is definitely not a tool to create fast Befunge programs, it's a tool to create big ones.
|
||||
And while it optimize your program quite a bit, a manual written program will always be faster and smaller.
|
||||
|
||||
So for bigger programs you will also need an fast interpreter - otherwise the execution could take a long time
|
||||
|
||||
> **Tip:**
|
||||
> [BefunExec](/programs/view/BefunGen) is a pretty fast multi-threaded interpreter.
|
||||
|
||||
|
||||
###Program size
|
||||
|
||||
While the generated programs are strictly bound to the Befunge-93, they can become pretty big (bigger than 80x25).
|
||||
|
||||
So you have to either use a Befunge-93 interpreter which ignores the size limit (many interpreters do that)
|
||||
or use a Befunge-98 interpreter.
|
||||
|
||||
> **Tip:**
|
||||
> [BefunExec](/programs/view/BefunGen), as you probably can assume, has no "real" size limit to it.
|
@ -0,0 +1,29 @@
|
||||
Here a few tricks for programming with BefunGen:
|
||||
|
||||
###Horizontal size
|
||||
|
||||
Normally a program only grows in height, the more instructions your program has the greater is the height of the generated code.
|
||||
|
||||
So it is kinda bad when you have one really long line, because the width of the program is determined by the longest line.
|
||||
So its good to try to avoid long lines for the sake of smaller - more compressed programs.
|
||||
|
||||
Here are a few common cases which compile to long single lines:
|
||||
|
||||
- Deep Nesting (e.g. multiple nested `for` loops)
|
||||
- A lot of consecutive `elsif` statements
|
||||
- `Switch` statements with a lot of cases
|
||||
- Function calls with a lot of parameters
|
||||
- Very long arrays
|
||||
- Complex "one-line" statements (e.g. multiple nested method calls)
|
||||
|
||||
Neither of these things has any real consequence - except your program having a lot of empty space.
|
||||
|
||||
###Display as array
|
||||
|
||||
If you are in need of a really big array, or of a 2 dimensional array you can use the display for that.
|
||||
|
||||
The display is an easy way of having an **global** 2dimensional array, that is easily visible to the user.
|
||||
|
||||
###Constants
|
||||
|
||||
You can without hesitation use constants in your program, they are inlined on compilation and have no performance cost at all.
|
@ -0,0 +1,14 @@
|
||||
###Hello World
|
||||
|
||||
A simple "Hello World"
|
||||
|
||||
```textfunge
|
||||
program example
|
||||
begin
|
||||
out "Hello World\r\n";
|
||||
quit;
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
> **Note:** *This and other examples are included in the BefunGen download*
|
@ -0,0 +1,77 @@
|
||||
###Sieve of Erasthothenes
|
||||
|
||||
Calculates the primes between 0 and 19200 with the sieve of Erasthothenes
|
||||
|
||||
```textfunge
|
||||
program SieveOfEratosthenes : display[240, 80]
|
||||
begin
|
||||
// Init all Fields with '?'
|
||||
init();
|
||||
|
||||
// Set an 'X' to every Primenumberfield
|
||||
calculate();
|
||||
|
||||
// Output the primes
|
||||
output();
|
||||
end
|
||||
|
||||
void init()
|
||||
var
|
||||
int i;
|
||||
begin
|
||||
for(i = 0; i < DISPLAY_SIZE; i++) do
|
||||
display[i % DISPLAY_WIDTH, i / DISPLAY_WIDTH] = '?';
|
||||
end
|
||||
|
||||
display[0, 0] = ' ';
|
||||
display[1, 0] = ' ';
|
||||
end
|
||||
|
||||
void calculate()
|
||||
var
|
||||
int i;
|
||||
begin
|
||||
for(i = 2; i < DISPLAY_SIZE; i++) do
|
||||
doNumber(i);
|
||||
end
|
||||
end
|
||||
|
||||
void doNumber(int i)
|
||||
var
|
||||
char c;
|
||||
begin
|
||||
c = display[i % DISPLAY_WIDTH, i / DISPLAY_WIDTH];
|
||||
|
||||
if (c == 'X' || c == ' ') then
|
||||
return;
|
||||
elsif (c == '?') then
|
||||
display[i % DISPLAY_WIDTH, i / DISPLAY_WIDTH] = 'X';
|
||||
|
||||
clear(i);
|
||||
end
|
||||
end
|
||||
|
||||
void clear(int n)
|
||||
var
|
||||
int p;
|
||||
begin
|
||||
for(p = 2*n; p < DISPLAY_SIZE; p += n) do
|
||||
display[p % DISPLAY_WIDTH, p / DISPLAY_WIDTH] = ' ';
|
||||
end
|
||||
end
|
||||
|
||||
void output()
|
||||
var
|
||||
int i;
|
||||
begin
|
||||
out "Prime Numbers:\r\n";
|
||||
for(i = 2; i < DISPLAY_SIZE; i++) do
|
||||
if (display[i % DISPLAY_WIDTH, i / DISPLAY_WIDTH] == 'X') then
|
||||
outf i, "\r\n";
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
> **Note:** *This and other examples are included in the BefunGen download*
|
@ -0,0 +1,43 @@
|
||||
###The Euclidean algorithm
|
||||
|
||||
A simple, *recursive* implementation of the [euclidian algorithm](http://en.wikipedia.org/wiki/Euclidean_algorithm)
|
||||
|
||||
```textfunge
|
||||
program EuclidianAlgo
|
||||
var
|
||||
int a, b, eucl;
|
||||
begin
|
||||
out "Please insert numer [a]\r\n";
|
||||
in a;
|
||||
out "Please insert numer [b]\r\n";
|
||||
in b;
|
||||
|
||||
eucl = euclid(a, b);
|
||||
|
||||
outf "euclid(", a, ",", b, ") = ", eucl, "\r\n";
|
||||
|
||||
outf a, "/", b, " = ", (a/eucl), "/", (b/eucl), "\r\n";
|
||||
|
||||
quit;
|
||||
end
|
||||
|
||||
int euclid(int a, int b)
|
||||
begin
|
||||
if (a == 0) then
|
||||
return b;
|
||||
else
|
||||
if (b == 0) then
|
||||
return a;
|
||||
else
|
||||
if (a > b) then
|
||||
return euclid(a - b, b);
|
||||
else
|
||||
return euclid(a, b - a);
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
> **Note:** *This and other examples are included in the BefunGen download*
|
@ -0,0 +1,38 @@
|
||||
###Fibonacci numbers
|
||||
|
||||
Calculates the [Fibonacci sequence](http://en.wikipedia.org/wiki/Fibonacci_number)
|
||||
|
||||
```textfunge
|
||||
program Fibbonacci
|
||||
var
|
||||
int i;
|
||||
begin
|
||||
out "Input the maximum\r\n";
|
||||
in i;
|
||||
|
||||
doFiber(i);
|
||||
quit;
|
||||
end
|
||||
|
||||
void doFiber(int max)
|
||||
var
|
||||
int last := 0;
|
||||
int curr := 1;
|
||||
int tmp;
|
||||
begin
|
||||
repeat
|
||||
if (last > 0) then
|
||||
out ",";
|
||||
end
|
||||
|
||||
out curr;
|
||||
|
||||
tmp = curr + last;
|
||||
last = curr;
|
||||
curr = tmp;
|
||||
until (last > max)
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
> **Note:** *This and other examples are included in the BefunGen download*
|
@ -0,0 +1,37 @@
|
||||
###Fizz Buzz
|
||||
|
||||
A simple implementation of the [Fizz Buzz](http://en.wikipedia.org/wiki/Fizz_buzz) game.
|
||||
|
||||
```textfunge
|
||||
program FizzBuzz
|
||||
begin
|
||||
fizzbuzz();
|
||||
quit;
|
||||
end
|
||||
|
||||
void fizzbuzz()
|
||||
var
|
||||
int i := 0;
|
||||
begin
|
||||
i = 1;
|
||||
|
||||
while (i < 100) do
|
||||
if (i % 3 == 0 && i % 5 == 0) then
|
||||
out "FizzBuzz";
|
||||
elsif (i % 3 == 0) then
|
||||
out "Fizz";
|
||||
elsif (i % 5 == 0) then
|
||||
out "Buzz";
|
||||
else
|
||||
out i;
|
||||
end
|
||||
|
||||
out "\r\n";
|
||||
|
||||
i++;
|
||||
end
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
> **Note:** *This and other examples are included in the BefunGen download*
|
107
www/data/programs/desc/BefunGen/03_Examples/06_PI Calc.markdown
Normal file
107
www/data/programs/desc/BefunGen/03_Examples/06_PI Calc.markdown
Normal file
@ -0,0 +1,107 @@
|
||||
###PI Calculation
|
||||
|
||||
Calculates PI to a certain degree with the Monte Carlo algorithm
|
||||
|
||||
```textfunge
|
||||
program PICalc : display[256, 256]
|
||||
const
|
||||
// WIDTH = HEIGHT = 4^SIZE
|
||||
int SIZE := 4;
|
||||
|
||||
// Total Count
|
||||
int COUNT := 65536;
|
||||
|
||||
// After n Steps print out intermediate result
|
||||
int STEPS := 4096;
|
||||
|
||||
global
|
||||
int hit;
|
||||
int miss;
|
||||
var
|
||||
int i;
|
||||
begin
|
||||
hit = 0;
|
||||
miss = 0;
|
||||
|
||||
for(i = 0; i < COUNT; i++) do
|
||||
drop();
|
||||
|
||||
if (i % STEPS == 0) then
|
||||
output();
|
||||
end
|
||||
end
|
||||
|
||||
output();
|
||||
end
|
||||
|
||||
void output()
|
||||
begin
|
||||
// PI := (4 * hit)/(total)
|
||||
outf "PI = ", (4*hit), "/", (hit+miss), " = ", floatDiv(4 * hit, miss + hit), "\r\n";
|
||||
end
|
||||
|
||||
void drop()
|
||||
var
|
||||
int x, y;
|
||||
|
||||
char c;
|
||||
begin
|
||||
x = RAND[SIZE];
|
||||
y = RAND[SIZE];
|
||||
|
||||
c = display[x, y];
|
||||
|
||||
display[x, y] = 'X';
|
||||
|
||||
if (c == '#') then
|
||||
hit++;
|
||||
elsif (c == ' ') then
|
||||
miss++;
|
||||
else
|
||||
out "FATAL ERROR 0x01";
|
||||
end
|
||||
|
||||
display[x, y] = c;
|
||||
end
|
||||
|
||||
// Gives a string containing a/b as float back
|
||||
char[10] floatDiv(int a, int b)
|
||||
var
|
||||
char[10] result;
|
||||
int mantissa;
|
||||
int pos := 0;
|
||||
begin
|
||||
mantissa = a / b;
|
||||
|
||||
repeat
|
||||
if (pos == 10) then
|
||||
return result;
|
||||
end
|
||||
|
||||
result[pos++] = (char)((int)'0' + (mantissa % 10));
|
||||
mantissa /= 10;
|
||||
until (mantissa == 0)
|
||||
|
||||
if (pos == 10) then
|
||||
return result;
|
||||
end
|
||||
result[pos++] = ',';
|
||||
|
||||
for(;;) do
|
||||
if (pos == 10) then
|
||||
return result;
|
||||
end
|
||||
|
||||
a %= b;
|
||||
a *= 10;
|
||||
result[pos++] = (char)((int)'0' + (a / b));
|
||||
end
|
||||
|
||||
return result;
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
> **Note:** This program needs a special initial display value to work - see the download to execute it.
|
||||
|
||||
> **Note:** *This and other examples are included in the BefunGen download*
|
@ -0,0 +1,285 @@
|
||||
###Befunge-93 interpreter
|
||||
|
||||
An Befunge-93 interpreter
|
||||
|
||||
```textfunge
|
||||
program BefInterpreter : display[60, 30]
|
||||
const
|
||||
int STACKSIZE := 16;
|
||||
global
|
||||
int[4] DELTA_IDX_X;
|
||||
int[4] DELTA_IDX_Y;
|
||||
|
||||
bool running;
|
||||
|
||||
int PC_X;
|
||||
int PC_Y;
|
||||
|
||||
int D_X;
|
||||
int D_Y;
|
||||
|
||||
bool stringmode;
|
||||
|
||||
int[16] stack;
|
||||
int stackHead;
|
||||
begin
|
||||
Init();
|
||||
|
||||
while (running) do
|
||||
execute();
|
||||
move();
|
||||
end
|
||||
|
||||
quit;
|
||||
end
|
||||
|
||||
void Init()
|
||||
begin
|
||||
DELTA_IDX_X[0] = 1;
|
||||
DELTA_IDX_X[1] = 0;
|
||||
DELTA_IDX_X[2] = -1;
|
||||
DELTA_IDX_X[3] = 0;
|
||||
|
||||
DELTA_IDX_Y[0] = 0;
|
||||
DELTA_IDX_Y[1] = -1;
|
||||
DELTA_IDX_Y[2] = 0;
|
||||
DELTA_IDX_Y[3] = 1;
|
||||
|
||||
stackHead = 0;
|
||||
|
||||
PC_X = 0;
|
||||
PC_Y = 0;
|
||||
|
||||
D_X = 1;
|
||||
D_Y = 0;
|
||||
|
||||
stringmode = false;
|
||||
|
||||
running = true;
|
||||
end
|
||||
|
||||
void execute()
|
||||
var
|
||||
char c;
|
||||
|
||||
int tmp, tmp2, tmp3;
|
||||
begin
|
||||
c = display[PC_X, PC_Y];
|
||||
|
||||
if (stringmode && c != '"') then
|
||||
push((int)c);
|
||||
return;
|
||||
end
|
||||
|
||||
switch(c)
|
||||
begin
|
||||
case ' ':
|
||||
// NOP
|
||||
end
|
||||
case '0':
|
||||
push(0);
|
||||
end
|
||||
case '1':
|
||||
push(1);
|
||||
end
|
||||
case '2':
|
||||
push(2);
|
||||
end
|
||||
case '3':
|
||||
push(3);
|
||||
end
|
||||
case '4':
|
||||
push(4);
|
||||
end
|
||||
case '5':
|
||||
push(5);
|
||||
end
|
||||
case '6':
|
||||
push(6);
|
||||
end
|
||||
case '7':
|
||||
push(7);
|
||||
end
|
||||
case '8':
|
||||
push(8);
|
||||
end
|
||||
case '9':
|
||||
push(9);
|
||||
end
|
||||
end
|
||||
|
||||
switch(c)
|
||||
begin
|
||||
case '+':
|
||||
push(pop() + pop());
|
||||
end
|
||||
case '-':
|
||||
tmp = pop();
|
||||
push(pop() - tmp);
|
||||
end
|
||||
case '*':
|
||||
push(pop() * pop());
|
||||
end
|
||||
case '/':
|
||||
tmp = pop();
|
||||
push(pop() / tmp);
|
||||
end
|
||||
case '%':
|
||||
tmp = pop();
|
||||
push(pop() % tmp);
|
||||
end
|
||||
case '!':
|
||||
push((int)(!popBool()));
|
||||
end
|
||||
case '`':
|
||||
tmp = pop();
|
||||
push((int)(pop() > tmp));
|
||||
end
|
||||
case '>':
|
||||
D_X = 1;
|
||||
D_Y = 0;
|
||||
end
|
||||
case '<':
|
||||
D_X = -1;
|
||||
D_Y = 0;
|
||||
end
|
||||
case '^':
|
||||
D_X = 0;
|
||||
D_Y = -1;
|
||||
end
|
||||
case 'v':
|
||||
D_X = 0;
|
||||
D_Y = 1;
|
||||
end
|
||||
case '?':
|
||||
tmp = RAND[1];
|
||||
D_X = DELTA_IDX_X[tmp];
|
||||
D_Y = DELTA_IDX_Y[tmp];
|
||||
end
|
||||
end
|
||||
|
||||
switch(c)
|
||||
begin
|
||||
case '_':
|
||||
if (popBool()) then
|
||||
D_X = DELTA_IDX_X[2];
|
||||
D_Y = DELTA_IDX_Y[2];
|
||||
else
|
||||
D_X = DELTA_IDX_X[0];
|
||||
D_Y = DELTA_IDX_Y[0];
|
||||
end
|
||||
end
|
||||
case '|':
|
||||
if (popBool()) then
|
||||
D_X = DELTA_IDX_X[1];
|
||||
D_Y = DELTA_IDX_Y[1];
|
||||
else
|
||||
D_X = DELTA_IDX_X[3];
|
||||
D_Y = DELTA_IDX_Y[3];
|
||||
end
|
||||
end
|
||||
case '"':
|
||||
stringmode = !stringmode;
|
||||
end
|
||||
case ':':
|
||||
push(peek());
|
||||
end
|
||||
case '\\':
|
||||
tmp = pop();
|
||||
tmp2 = pop();
|
||||
push(tmp);
|
||||
push(tmp2);
|
||||
end
|
||||
case '$':
|
||||
pop();
|
||||
end
|
||||
case '.':
|
||||
out pop();
|
||||
end
|
||||
case ',':
|
||||
out popChar();
|
||||
end
|
||||
case '#':
|
||||
move();
|
||||
end
|
||||
case 'g':
|
||||
tmp = pop();
|
||||
tmp2 = pop();
|
||||
if (tmp >= 0 && tmp2 >= 0 && tmp2 < DISPLAY_WIDTH && tmp < DISPLAY_HEIGHT) then
|
||||
push((int)display[tmp2, tmp]);
|
||||
else
|
||||
push(0);
|
||||
end
|
||||
end
|
||||
case 'p':
|
||||
tmp = pop();
|
||||
tmp2 = pop();
|
||||
if (tmp >= 0 && tmp2 >= 0 && tmp2 < DISPLAY_WIDTH && tmp < DISPLAY_HEIGHT) then
|
||||
display[tmp2, tmp] = popChar();
|
||||
else
|
||||
pop();
|
||||
end
|
||||
end
|
||||
case '&':
|
||||
in tmp;
|
||||
push(tmp);
|
||||
end
|
||||
case '~':
|
||||
in tmp3;
|
||||
push((int)tmp3);
|
||||
end
|
||||
case '@':
|
||||
out "\r\n\r\n >> FINISHED";
|
||||
running = false;
|
||||
end
|
||||
default:
|
||||
// NOP
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
void move()
|
||||
begin
|
||||
PC_X += D_X + DISPLAY_WIDTH;
|
||||
PC_Y += D_Y + DISPLAY_HEIGHT;
|
||||
|
||||
PC_X %= DISPLAY_WIDTH;
|
||||
PC_Y %= DISPLAY_HEIGHT;
|
||||
end
|
||||
|
||||
void push(int v)
|
||||
begin
|
||||
stack[stackhead++] = v;
|
||||
end
|
||||
|
||||
int pop()
|
||||
begin
|
||||
if (stackhead == 0) then
|
||||
return 0;
|
||||
end
|
||||
|
||||
return stack[--stackhead];
|
||||
end
|
||||
|
||||
char popChar()
|
||||
begin
|
||||
return (char)pop();
|
||||
end
|
||||
|
||||
bool popBool()
|
||||
begin
|
||||
return (bool)pop();
|
||||
end
|
||||
|
||||
int peek()
|
||||
begin
|
||||
if (stackhead == 0) then
|
||||
return 0;
|
||||
end
|
||||
|
||||
return stack[stackhead - 1];
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
> **Note:** *This and other examples are included in the BefunGen download*
|
@ -0,0 +1,224 @@
|
||||
###Sudoku Generator
|
||||
|
||||
Generates a random (but valid) Sudoku puzzle
|
||||
|
||||
```textfunge
|
||||
program SudoGen : display[17, 17]
|
||||
const
|
||||
char CHR_EMPTY := ' ';
|
||||
char CHR_UNKNOWN := ' ';
|
||||
char CHR_BORDER := '#';
|
||||
char CHR_INTERSECT := '+';
|
||||
char CHR_HORZ := '-';
|
||||
char CHR_VERT := '|';
|
||||
begin
|
||||
Init();
|
||||
|
||||
Create();
|
||||
|
||||
Obfuscate();
|
||||
end
|
||||
|
||||
void Init()
|
||||
var
|
||||
int x, y;
|
||||
begin
|
||||
for (y = 0; y < DISPLAY_HEIGHT; y++) do
|
||||
for (x = 0; x < DISPLAY_WIDTH; x++) do
|
||||
if (x % 2 == 0 && y % 2 == 0) then
|
||||
display[x, y] = CHR_EMPTY;
|
||||
elsif ((x + 1) % 6 == 0 || (y + 1) % 6 == 0) then
|
||||
display[x, y] = CHR_BORDER;
|
||||
elsif ((x - 1) % 2 == 0 && (y - 1) % 2 == 0) then
|
||||
display[x, y] = CHR_INTERSECT;
|
||||
elsif ((x - 1) % 2 == 0 && y % 2 == 0) then
|
||||
display[x, y] = CHR_VERT;
|
||||
elsif (x % 2 == 0 && (y - 1) % 2 == 0) then
|
||||
display[x, y] = CHR_HORZ;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
bool Create()
|
||||
var
|
||||
int x, y;
|
||||
|
||||
int on;
|
||||
int n;
|
||||
begin
|
||||
if (!IsValid()) then
|
||||
return false;
|
||||
end
|
||||
|
||||
on = rand[3] % 9;
|
||||
|
||||
for (y = 0; y < 9; y++) do
|
||||
for (x = 0; x < 9; x++) do
|
||||
if (display[x * 2, y * 2] == CHR_EMPTY) then
|
||||
for (n = 0; n < 9; n++) do
|
||||
display[x * 2, y * 2] = (char)((int)'1' + ((n + on) % 9));
|
||||
|
||||
if (Create()) then
|
||||
return true;
|
||||
end
|
||||
|
||||
display[x * 2, y * 2] = CHR_EMPTY;
|
||||
end
|
||||
|
||||
return false;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return true;
|
||||
end
|
||||
|
||||
bool IsValid()
|
||||
var
|
||||
int x, y;
|
||||
int p;
|
||||
int c;
|
||||
int[9] vals;
|
||||
begin
|
||||
// Rows
|
||||
|
||||
for (y = 0; y < 9; y++) do
|
||||
for (p = 0; p < 9; ) do
|
||||
vals[p++] = 0;
|
||||
end
|
||||
|
||||
for (x = 0; x < 9; x++) do
|
||||
if (display[x * 2, y * 2] != CHR_EMPTY) then
|
||||
vals[((int)display[x * 2, y * 2]) - ((int)'1')]++;
|
||||
end
|
||||
end
|
||||
|
||||
for (p = 0; p < 9; p++) do
|
||||
if (vals[p] > 1) then
|
||||
return false;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// Cols
|
||||
|
||||
for (x = 0; x < 9; x++) do
|
||||
for (p = 0; p < 9; ) do
|
||||
vals[p++] = 0;
|
||||
end
|
||||
|
||||
for (y = 0; y < 9; y++) do
|
||||
if (display[x * 2, y * 2] != CHR_EMPTY) then
|
||||
vals[((int)display[x * 2, y * 2]) - ((int)'1')]++;
|
||||
end
|
||||
end
|
||||
|
||||
for (p = 0; p < 9; p++) do
|
||||
if (vals[p] > 1) then
|
||||
return false;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// Rects
|
||||
|
||||
for (c = 0; c < 9; c++) do
|
||||
for (p = 0; p < 9; ) do
|
||||
vals[p++] = 0;
|
||||
end
|
||||
|
||||
for (x = (c / 3) * 3; x < (c / 3 + 1) * 3; x++) do
|
||||
for (y = (c % 3) * 3; y < (c % 3 + 1) * 3; y++) do
|
||||
if (display[x * 2, y * 2] != CHR_EMPTY) then
|
||||
vals[((int)display[x * 2, y * 2]) - ((int)'1')]++;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
for (p = 0; p < 9; p++) do
|
||||
if (vals[p] > 1) then
|
||||
return false;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return true;
|
||||
|
||||
end
|
||||
|
||||
bool isRemovable(int x, int y)
|
||||
var
|
||||
int v;
|
||||
int p;
|
||||
int rx, ry;
|
||||
bool[9] vals;
|
||||
begin
|
||||
|
||||
|
||||
v = ((int)display[x * 2, y * 2]) - ((int)'1');
|
||||
|
||||
for (p = 0; p < 9; ) do
|
||||
vals[p++] = false;
|
||||
end
|
||||
|
||||
// Row
|
||||
for (p = 0; p < 9; p++) do
|
||||
if (display[p * 2, y * 2] != CHR_UNKNOWN) then
|
||||
vals[((int)display[p * 2, y * 2]) - ((int)'1')] = true;
|
||||
end
|
||||
end
|
||||
|
||||
// Col
|
||||
for (p = 0; p < 9; p++) do
|
||||
if (display[x * 2, p * 2] != CHR_UNKNOWN) then
|
||||
vals[((int)display[x * 2, p * 2]) - ((int)'1')] = true;
|
||||
end
|
||||
end
|
||||
|
||||
//Rect
|
||||
for (rx = (x / 3) * 3; rx < (x / 3 + 1) * 3; rx++) do
|
||||
for (ry = (y / 3) * 3; ry < (y / 3 + 1) * 3; ry++) do
|
||||
if (display[rx * 2, rx * 2] != CHR_UNKNOWN) then
|
||||
vals[((int)display[rx * 2, ry * 2]) - ((int)'1')] = true;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
//Test
|
||||
for (p = 0; p < 9; p++) do
|
||||
if (!vals[p] && p != v) then
|
||||
return false;
|
||||
end
|
||||
end
|
||||
|
||||
return true;
|
||||
end
|
||||
|
||||
void Obfuscate()
|
||||
var
|
||||
int ox, oy;
|
||||
|
||||
int x, y;
|
||||
begin
|
||||
ox = rand[3];
|
||||
oy = rand[3];
|
||||
|
||||
for (x = ox; x < ox + 9; x++) do
|
||||
for (y = oy; y < oy + 9; y++) do
|
||||
if (display[(x % 9) * 2, (y % 9) * 2] != CHR_UNKNOWN) then
|
||||
if (isRemovable(x % 9, y % 9)) then
|
||||
display[(x % 9) * 2, (y % 9) * 2] = CHR_UNKNOWN;
|
||||
Obfuscate();
|
||||
return;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return;
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
> **Note:** *This and other examples are included in the BefunGen download*
|
@ -0,0 +1,101 @@
|
||||
###Conway's Game of Life
|
||||
|
||||
A simulation of [Conway's Game of Life](http://en.wikipedia.org/wiki/Conway%27s_Game_of_Life)
|
||||
|
||||
```textfunge
|
||||
program GameOfLife : display[40, 40]
|
||||
const
|
||||
char FIELD_UNSET := ' ';
|
||||
char FIELD_SET := 'O';
|
||||
char FIELD_PREBORN := 'o';
|
||||
char FIELD_PREDEAD := 'Q';
|
||||
begin
|
||||
Init();
|
||||
|
||||
Run();
|
||||
end
|
||||
|
||||
void Init()
|
||||
var
|
||||
int x, y;
|
||||
begin
|
||||
for (x = 0; x < DISPLAY_WIDTH; x++)
|
||||
do
|
||||
for (y = 0; y < DISPLAY_HEIGHT; y++)
|
||||
do
|
||||
if (display[x, y] != FIELD_UNSET) then
|
||||
display[x, y] = FIELD_SET;
|
||||
else
|
||||
display[x, y] = FIELD_UNSET;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
void Run()
|
||||
var
|
||||
int i := 0;
|
||||
begin
|
||||
for(;;i++) do
|
||||
Tick();
|
||||
OUTF "Tick Nr " , i , "\r\n";
|
||||
end
|
||||
end
|
||||
|
||||
void Tick()
|
||||
var
|
||||
int x, y;
|
||||
int nc;
|
||||
begin
|
||||
for (x = 0; x < DISPLAY_WIDTH; x++) do
|
||||
for (y = 0; y < DISPLAY_HEIGHT; y++) do
|
||||
nc = GetNeighborCount(x, y);
|
||||
|
||||
if (display[x, y] == FIELD_SET) then
|
||||
if (nc < 2) then // Underpopulation
|
||||
display[x, y] = FIELD_PREDEAD;
|
||||
elsif (nc > 3) then // Overcrowding
|
||||
display[x, y] = FIELD_PREDEAD;
|
||||
end
|
||||
else
|
||||
if (nc == 3) then // It lives !
|
||||
display[x, y] = FIELD_PREBORN;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
for (x = 0; x < DISPLAY_WIDTH; x++) do
|
||||
for (y = 0; y < DISPLAY_HEIGHT; y++) do
|
||||
if (display[x, y] == FIELD_PREBORN) then
|
||||
display[x, y] = FIELD_SET;
|
||||
elsif (display[x, y] == FIELD_PREDEAD) then
|
||||
display[x, y] = FIELD_UNSET;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
int GetNeighborCount(int x, int y)
|
||||
var
|
||||
int r;
|
||||
begin
|
||||
r = 0;
|
||||
|
||||
r += (int)(display[x - 1, y - 1] == FIELD_SET || display[x - 1, y - 1] == FIELD_PREDEAD);
|
||||
r += (int)(display[x + 0, y - 1] == FIELD_SET || display[x + 0, y - 1] == FIELD_PREDEAD);
|
||||
r += (int)(display[x + 1, y - 1] == FIELD_SET || display[x + 1, y - 1] == FIELD_PREDEAD);
|
||||
r += (int)(display[x - 1, y + 0] == FIELD_SET || display[x - 1, y + 0] == FIELD_PREDEAD);
|
||||
r += (int)(display[x + 1, y + 0] == FIELD_SET || display[x + 1, y + 0] == FIELD_PREDEAD);
|
||||
r += (int)(display[x - 1, y + 1] == FIELD_SET || display[x - 1, y + 1] == FIELD_PREDEAD);
|
||||
r += (int)(display[x + 0, y + 1] == FIELD_SET || display[x + 0, y + 1] == FIELD_PREDEAD);
|
||||
r += (int)(display[x + 1, y + 1] == FIELD_SET || display[x + 1, y + 1] == FIELD_PREDEAD);
|
||||
|
||||
return r;
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
> **Note:** This programs needs the options `Safe Boolean Convert` and `Prevent Display Overflow` enabled
|
||||
|
||||
> **Note:** *This and other examples are included in the BefunGen download*
|
252
www/data/programs/desc/BefunGen/03_Examples/10_Maze Gen.markdown
Normal file
252
www/data/programs/desc/BefunGen/03_Examples/10_Maze Gen.markdown
Normal file
@ -0,0 +1,252 @@
|
||||
###Maze Generator
|
||||
|
||||
Generates a Maze on the display with the [Hunt&Kill algorithm](http://weblog.jamisbuck.org/2011/1/24/maze-generation-hunt-and-kill-algorithm) - thens solves is by recursively trying every path
|
||||
|
||||
```textfunge
|
||||
program MazeGen : display[131, 51]
|
||||
const
|
||||
char CHR_UNSET := '@';
|
||||
char CHR_WALL := '#';
|
||||
char CHR_FLOOR := ' ';
|
||||
char CHR_PATH := '+';
|
||||
var
|
||||
bool succ;
|
||||
begin
|
||||
Init();
|
||||
|
||||
Create();
|
||||
|
||||
succ = Solve(1, 1, DISPLAY_WIDTH - 2, DISPLAY_HEIGHT - 2);
|
||||
|
||||
if (succ) then
|
||||
out "Maze solved";
|
||||
else
|
||||
out "Fatal Error: Maze could not be solved";
|
||||
end
|
||||
end
|
||||
|
||||
void Init()
|
||||
var
|
||||
int x, y;
|
||||
begin
|
||||
for(x = 0; x < DISPLAY_WIDTH; x++) do
|
||||
for(y = 0; y < DISPLAY_HEIGHT; y++) do
|
||||
if (x == 0 || y == 0 || x == DISPLAY_WIDTH - 1 || y == DISPLAY_HEIGHT - 1 || (x % 2 == 0 && y % 2 == 0)) then
|
||||
display[x,y] = CHR_WALL;
|
||||
ELSE
|
||||
display[x,y] = CHR_UNSET;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
void Create()
|
||||
begin
|
||||
Kill(1, 1);
|
||||
end
|
||||
|
||||
void Kill(int x, int y)
|
||||
var
|
||||
bool top;
|
||||
bool left;
|
||||
bool bot;
|
||||
bool right;
|
||||
int possibleDirections;
|
||||
int direction;
|
||||
begin
|
||||
for(;;) do
|
||||
top = (display[x + 0, y - 1] == CHR_UNSET);
|
||||
left = (display[x - 1, y + 0] == CHR_UNSET);
|
||||
bot = (display[x + 0, y + 1] == CHR_UNSET);
|
||||
right = (display[x + 1, y + 0] == CHR_UNSET);
|
||||
|
||||
possibleDirections = 0;
|
||||
possibleDirections += (int)top;
|
||||
possibleDirections += (int)left;
|
||||
possibleDirections += (int)bot;
|
||||
possibleDirections += (int)right;
|
||||
|
||||
|
||||
if (possibleDirections == 0) then
|
||||
display[x, y] = CHR_FLOOR;
|
||||
|
||||
Hunt();
|
||||
|
||||
return;
|
||||
end
|
||||
|
||||
direction = rand[3] % possibleDirections;
|
||||
|
||||
if (top) then
|
||||
if (direction == 0) then
|
||||
if (display[x, y + 1] == CHR_UNSET) then
|
||||
display[x, y + 1] = CHR_WALL;
|
||||
end
|
||||
if (display[x + 1, y] == CHR_UNSET) then
|
||||
display[x + 1, y] = CHR_WALL;
|
||||
end
|
||||
if (display[x - 1, y] == CHR_UNSET) then
|
||||
display[x - 1, y] = CHR_WALL;
|
||||
end
|
||||
display[x, y] = CHR_FLOOR;
|
||||
y--;
|
||||
end
|
||||
direction--;
|
||||
end
|
||||
|
||||
if (left) then
|
||||
if (direction == 0) then
|
||||
if (display[x + 1, y] == CHR_UNSET) then
|
||||
display[x + 1, y] = CHR_WALL;
|
||||
end
|
||||
if (display[x, y + 1] == CHR_UNSET) then
|
||||
display[x, y + 1] = CHR_WALL;
|
||||
end
|
||||
if (display[x, y - 1] == CHR_UNSET) then
|
||||
display[x, y - 1] = CHR_WALL;
|
||||
end
|
||||
display[x, y] = CHR_FLOOR;
|
||||
x--;
|
||||
end
|
||||
direction--;
|
||||
end
|
||||
|
||||
if (bot) then
|
||||
if (direction == 0) then
|
||||
if (display[x, y - 1] == CHR_UNSET) then
|
||||
display[x, y - 1] = CHR_WALL;
|
||||
end
|
||||
if (display[x + 1, y] == CHR_UNSET) then
|
||||
display[x + 1, y] = CHR_WALL;
|
||||
end
|
||||
if (display[x - 1, y] == CHR_UNSET) then
|
||||
display[x - 1, y] = CHR_WALL;
|
||||
end
|
||||
display[x, y] = CHR_FLOOR;
|
||||
y++;
|
||||
end
|
||||
direction--;
|
||||
end
|
||||
|
||||
if (right) then
|
||||
if (direction == 0) then
|
||||
if (display[x - 1, y] == CHR_UNSET) then
|
||||
display[x - 1, y] = CHR_WALL;
|
||||
end
|
||||
if (display[x, y + 1] == CHR_UNSET) then
|
||||
display[x, y + 1] = CHR_WALL;
|
||||
end
|
||||
if (display[x, y - 1] == CHR_UNSET) then
|
||||
display[x, y - 1] = CHR_WALL;
|
||||
end
|
||||
display[x, y] = CHR_FLOOR;
|
||||
x++;
|
||||
end
|
||||
direction--;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
void Hunt()
|
||||
var
|
||||
int ox, oy;
|
||||
int fx, fy;
|
||||
int x, y;
|
||||
begin
|
||||
ox = rand[6];
|
||||
oy = rand[6];
|
||||
|
||||
ox %= DISPLAY_WIDTH;
|
||||
oy %= DISPLAY_HEIGHT;
|
||||
|
||||
for (fy = 0; fy < DISPLAY_HEIGHT; fy++) do
|
||||
for (fx = 0; fx < DISPLAY_WIDTH; fx++) do
|
||||
x = (fx + ox) % DISPLAY_WIDTH;
|
||||
y = (fy + oy) % DISPLAY_HEIGHT;
|
||||
|
||||
if (display[x, y] == CHR_UNSET) then
|
||||
if (y > 1 && ((x) % 2 != 0 || (y - 1) % 2 != 0)) then
|
||||
if (display[x, y - 1] == CHR_WALL && display[x, y - 2] == CHR_FLOOR) then
|
||||
display[x, y - 1] = CHR_FLOOR;
|
||||
Kill(x, y - 1);
|
||||
return;
|
||||
end
|
||||
end
|
||||
|
||||
if (x > 1 && ((x - 1) % 2 != 0 || (y) % 2 != 0)) then
|
||||
if (display[x - 1, y] == CHR_WALL && display[x - 2, y] == CHR_FLOOR) then
|
||||
display[x - 1, y] = CHR_FLOOR;
|
||||
Kill(x - 1, y);
|
||||
return;
|
||||
end
|
||||
end
|
||||
|
||||
if (y < DISPLAY_HEIGHT - 2 && ((x) % 2 != 0 || (y + 1) % 2 != 0)) then
|
||||
if (display[x, y + 1] == CHR_WALL && display[x, y + 2] == CHR_FLOOR) then
|
||||
display[x, y + 1] = CHR_FLOOR;
|
||||
Kill(x, y + 1);
|
||||
return;
|
||||
end
|
||||
end
|
||||
|
||||
if (x < DISPLAY_WIDTH - 2 && ((x + 1) % 2 != 0 || (y) % 2 != 0)) then
|
||||
if (display[x + 1, y] == CHR_WALL && display[x + 2, y] == CHR_FLOOR) then
|
||||
display[x + 1, y] = CHR_FLOOR;
|
||||
Kill(x + 1, y);
|
||||
return;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
bool Solve(int x, int y, int tx, int ty)
|
||||
var
|
||||
bool top, left, bot, right;
|
||||
begin
|
||||
top = display[x + 0, y - 1] == CHR_FLOOR;
|
||||
left = display[x - 1, y + 0] == CHR_FLOOR;
|
||||
bot = display[x + 0, y + 1] == CHR_FLOOR;
|
||||
right = display[x + 1, y + 0] == CHR_FLOOR;
|
||||
|
||||
display[x, y] = CHR_PATH;
|
||||
|
||||
if (x == tx && y == ty) then
|
||||
return true;
|
||||
end
|
||||
|
||||
if (top) then
|
||||
if (Solve(x, y - 1, tx, ty)) then
|
||||
return true;
|
||||
end
|
||||
end
|
||||
|
||||
if (left) then
|
||||
if (Solve(x - 1, y, tx, ty)) then
|
||||
return true;
|
||||
end
|
||||
end
|
||||
|
||||
if (bot) then
|
||||
if (Solve(x, y + 1, tx, ty)) then
|
||||
return true;
|
||||
end
|
||||
end
|
||||
|
||||
if (right) then
|
||||
if (Solve(x + 1, y, tx, ty)) then
|
||||
return true;
|
||||
end
|
||||
end
|
||||
|
||||
display[x, y] = CHR_FLOOR;
|
||||
|
||||
return false;
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
```
|
||||
|
||||
> **Note:** *This and other examples are included in the BefunGen download*
|
@ -0,0 +1,500 @@
|
||||
###Square It
|
||||
|
||||
An implementation of the game [Square It](http://en.wikipedia.org/wiki/Dots_and_Boxes). Complete with a computer opponent.
|
||||
|
||||
```textfunge
|
||||
program Square_It : display[34, 36] // 1 + 1+2*16 || 1 + 1+2*16 + 2
|
||||
const
|
||||
int FIELD_WIDTH := 16;
|
||||
int FIELD_HEIGHT := 16;
|
||||
|
||||
char CHAR_VERTICAL := '|';
|
||||
char CHAR_HORIZONTAL := '-';
|
||||
char CHAR_EMPTY := ' ';
|
||||
char CHAR_JUNCTION := '+';
|
||||
char CHAR_EMPTYFIELD := ' ';
|
||||
char CHAR_PLAYER_P1 := 'X';
|
||||
char CHAR_PLAYER_P2 := 'O';
|
||||
char CHAR_PLAYER_NEUTRAL := '#';
|
||||
|
||||
global
|
||||
char currPlayer;
|
||||
int p1_c, p2_c;
|
||||
begin
|
||||
restart();
|
||||
end
|
||||
|
||||
void restart()
|
||||
var
|
||||
int choice;
|
||||
begin
|
||||
for(;;) do
|
||||
Init();
|
||||
|
||||
outf "WHAT DO YOU WANT TO PLAY?",
|
||||
"\r\n",
|
||||
"0: Player vs Player",
|
||||
"\r\n",
|
||||
"1: Player vs Computer",
|
||||
"\r\n",
|
||||
"2: Computer vs Computer",
|
||||
"\r\n",
|
||||
"\r\n",
|
||||
"\r\n";
|
||||
|
||||
in choice;
|
||||
|
||||
if (choice == 0) then
|
||||
Game_P_v_P();
|
||||
elsif (choice == 1) then
|
||||
Game_P_v_NP();
|
||||
elsif (choice == 2) then
|
||||
Game_NP_v_NP();
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
void Game_P_v_P()
|
||||
var
|
||||
char winner;
|
||||
begin
|
||||
currPlayer = CHAR_PLAYER_P1;
|
||||
|
||||
repeat
|
||||
outf "PLAYER ", currPlayer, ":\r\n";
|
||||
DoPlayerTurn();
|
||||
until (GameFinished())
|
||||
|
||||
winner = GetWinningPlayer();
|
||||
|
||||
if (winner == CHAR_PLAYER_P1) then
|
||||
out ">> PLAYER 1 (X) WINS !\r\n\r\n";
|
||||
elsif (winner == CHAR_PLAYER_P2) then
|
||||
out ">> PLAYER 2 (O) WINS !\r\n\r\n";
|
||||
else
|
||||
out ">> DRAW !\r\n\r\n";
|
||||
end
|
||||
|
||||
return;
|
||||
end
|
||||
|
||||
void Game_P_v_NP()
|
||||
var
|
||||
char winner;
|
||||
begin
|
||||
currPlayer = CHAR_PLAYER_P1;
|
||||
|
||||
repeat
|
||||
if (currPlayer == CHAR_PLAYER_P1) then
|
||||
outf "PLAYER ", currPlayer, ":\r\n";
|
||||
DoPlayerTurn();
|
||||
else
|
||||
outf "COMPUTER ", currPlayer, ":\r\n";
|
||||
DoComputerTurn();
|
||||
end
|
||||
until (GameFinished())
|
||||
|
||||
winner = GetWinningPlayer();
|
||||
|
||||
if (winner == CHAR_PLAYER_P1) then
|
||||
out ">> YOU WIN !\r\n\r\n";
|
||||
elsif (winner == CHAR_PLAYER_P2) then
|
||||
out ">> YOU LOOSE !\r\n\r\n";
|
||||
else
|
||||
out ">> DRAW !\r\n\r\n";
|
||||
end
|
||||
|
||||
return;
|
||||
end
|
||||
|
||||
void Game_NP_v_NP()
|
||||
var
|
||||
char winner;
|
||||
begin
|
||||
currPlayer = CHAR_PLAYER_P1;
|
||||
|
||||
repeat
|
||||
outf "COMPUTER ", currPlayer, ":\r\n";
|
||||
DoComputerTurn();
|
||||
until (GameFinished())
|
||||
|
||||
winner = GetWinningPlayer();
|
||||
|
||||
if (winner == CHAR_PLAYER_P1) then
|
||||
out ">> PC1 (X) WINS !\r\n\r\n";
|
||||
elsif (winner == CHAR_PLAYER_P2) then
|
||||
out ">> PC2 (O) WINS !\r\n\r\n";
|
||||
else
|
||||
out ">> DRAW !\r\n\r\n";
|
||||
end
|
||||
|
||||
return;
|
||||
end
|
||||
|
||||
void Init()
|
||||
var
|
||||
int x, y;
|
||||
int px, py;
|
||||
begin
|
||||
for(x = 0; x < FIELD_WIDTH; x++) do
|
||||
if (x > 9) then
|
||||
display[2 + x*2, 0] = (char)(x + (int)'7');
|
||||
else
|
||||
display[2 + x*2, 0] = (char)(x + (int)'0');
|
||||
end
|
||||
end
|
||||
|
||||
for(y = 0; y < FIELD_HEIGHT; y++) do
|
||||
if (y > 9) then
|
||||
display[0, 2 + y*2] = (char)(y + (int)'7');
|
||||
else
|
||||
display[0, 2 + y*2] = (char)(y + (int)'0');
|
||||
end
|
||||
end
|
||||
|
||||
for(x = 0; x < FIELD_WIDTH; x++) do
|
||||
for(y = 0; y < FIELD_HEIGHT; y++) do
|
||||
px = 2 + x*2;
|
||||
py = 2 + y*2;
|
||||
|
||||
// CENTER
|
||||
display[px + 0, py + 0] = CHAR_EMPTYFIELD;
|
||||
|
||||
// TOP RIGHT
|
||||
display[px + 1, py + 1] = CHAR_JUNCTION;
|
||||
|
||||
// BOTTOM RIGHT
|
||||
display[px - 1, py + 1] = CHAR_JUNCTION;
|
||||
|
||||
// BOTTOM LEFT
|
||||
display[px - 1, py - 1] = CHAR_JUNCTION;
|
||||
|
||||
// TOP LEFT
|
||||
display[px + 1, py - 1] = CHAR_JUNCTION;
|
||||
|
||||
// TOP
|
||||
if (y == 0) then
|
||||
display[px + 0, py - 1] = CHAR_HORIZONTAL;
|
||||
else
|
||||
display[px + 0, py - 1] = CHAR_EMPTY;
|
||||
end
|
||||
|
||||
// RIGHT
|
||||
if (x == FIELD_WIDTH - 1) then
|
||||
display[px + 1, py + 0] = CHAR_VERTICAL;
|
||||
else
|
||||
display[px + 1, py + 0] = CHAR_EMPTY;
|
||||
end
|
||||
|
||||
// BOTTOM
|
||||
if (y == FIELD_HEIGHT - 1) then
|
||||
display[px + 0, py + 1] = CHAR_HORIZONTAL;
|
||||
else
|
||||
display[px + 0, py + 1] = CHAR_EMPTY;
|
||||
end
|
||||
|
||||
// LEFT
|
||||
if (x == 0) then
|
||||
display[px - 1, py + 0] = CHAR_VERTICAL;
|
||||
else
|
||||
display[px - 1, py + 0] = CHAR_EMPTY;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
void DoPlayerTurn()
|
||||
var
|
||||
char x,y,d;
|
||||
|
||||
int ix, iy, idx, idy;
|
||||
|
||||
int posx, posy;
|
||||
begin
|
||||
out " ";
|
||||
out "X: ";
|
||||
in x;
|
||||
out x;
|
||||
out " Y: ";
|
||||
in y;
|
||||
out y;
|
||||
out " Direction (U/D/L/R): ";
|
||||
in d;
|
||||
outf d, "\r\n";
|
||||
|
||||
if (x >= '0' && x <= '9') then
|
||||
ix = (int)x - (int)'0';
|
||||
elsif (x >= 'A' && x <= 'Z') then
|
||||
ix = (int)x - (int)'A';
|
||||
elsif (x >= 'a' && x <= 'z') then
|
||||
ix = (int)x - (int)'a';
|
||||
else
|
||||
out " ";
|
||||
out "ERROR - CANT PARSE INPUT (X)\r\n";
|
||||
DoPlayerTurn();
|
||||
return;
|
||||
end
|
||||
|
||||
if (y >= '0' && y <= '9') then
|
||||
iy = (int)y - (int)'0';
|
||||
elsif (y >= 'A' && y <= 'Z') then
|
||||
iy = (int)y - (int)'A';
|
||||
elsif (y >= 'a' && y <= 'z') then
|
||||
iy = (int)y - (int)'a';
|
||||
else
|
||||
out "ERROR - CANT PARSE INPUT (Y)\r\n";
|
||||
DoPlayerTurn();
|
||||
return;
|
||||
end
|
||||
|
||||
if (d == 'U' || d == 'u') then
|
||||
idx = 0;
|
||||
idy = -1;
|
||||
elsif (d == 'R' || d == 'r') then
|
||||
idx = 1;
|
||||
idy = 0;
|
||||
elsif (d == 'D' || d == 'd') then
|
||||
idx = 0;
|
||||
idy = 1;
|
||||
elsif (d == 'L' || d == 'l') then
|
||||
idx = -1;
|
||||
idy = 0;
|
||||
else
|
||||
out " ";
|
||||
out "ERROR - CANT PARSE INPUT (DIRECTION)\r\n";
|
||||
DoPlayerTurn();
|
||||
return;
|
||||
end
|
||||
|
||||
posx = 2 + ix*2 + idx;
|
||||
posy = 2 + iy*2 + idy;
|
||||
|
||||
if (display[posx, posy] == CHAR_EMPTY) then
|
||||
DoTurn(ix, iy, idx, idy);
|
||||
|
||||
return;
|
||||
else
|
||||
out " ";
|
||||
out "ERROR - FIELD ALREADY SET\r\n";
|
||||
DoPlayerTurn();
|
||||
return;
|
||||
end
|
||||
end
|
||||
|
||||
void DoTurn(int x, int y, int dx, int dy)
|
||||
var
|
||||
int posx, posy;
|
||||
|
||||
bool t_a, t_b;
|
||||
begin
|
||||
posx = 2 + 2*x;
|
||||
posy = 2 + 2*y;
|
||||
|
||||
if (dx == 0) then
|
||||
display[posx + dx, posy + dy] = CHAR_HORIZONTAL;
|
||||
else
|
||||
display[posx + dx, posy + dy] = CHAR_VERTICAL;
|
||||
end
|
||||
|
||||
t_a = testField(x, y);
|
||||
t_b = testField(x + dx, y + dy);
|
||||
|
||||
if (! (t_a || t_b)) then
|
||||
SwitchPlayer();
|
||||
end
|
||||
end
|
||||
|
||||
void DoComputerTurn()
|
||||
begin
|
||||
if (FindComputerTurn(3)) then
|
||||
return;
|
||||
end
|
||||
|
||||
if (FindComputerTurn(1)) then
|
||||
return;
|
||||
end
|
||||
|
||||
if (FindComputerTurn(0)) then
|
||||
return;
|
||||
end
|
||||
|
||||
if (FindComputerTurn(2)) then
|
||||
return;
|
||||
end
|
||||
|
||||
while (true) do out "ERROR"; end
|
||||
end
|
||||
|
||||
bool FindComputerTurn(int target_surr)
|
||||
var
|
||||
int c_x, c_y;
|
||||
int x, y;
|
||||
int r_x, r_y, r_d;
|
||||
|
||||
int c_i, i;
|
||||
int dx, dy;
|
||||
begin
|
||||
r_x = RAND[4];
|
||||
r_y = RAND[4];
|
||||
r_d = RAND[1];
|
||||
|
||||
for(c_x = 0; c_x < FIELD_WIDTH; c_x++) do
|
||||
for(c_y = 0; c_y < FIELD_HEIGHT; c_y++) do
|
||||
x = (c_x + r_x) % FIELD_WIDTH;
|
||||
y = (c_y + r_y) % FIELD_HEIGHT;
|
||||
|
||||
if (getSurrounding(x, y) == target_surr) then
|
||||
for(c_i = 0; c_i < 4; c_i++) do
|
||||
i = (c_i + r_d) % 4;
|
||||
|
||||
switch(i)
|
||||
begin
|
||||
case 0:
|
||||
dx = 0;
|
||||
dy = -1;
|
||||
end
|
||||
case 1:
|
||||
dx = 0;
|
||||
dy = 1;
|
||||
end
|
||||
case 2:
|
||||
dx = -1;
|
||||
dy = 0;
|
||||
end
|
||||
case 3:
|
||||
dx = 1;
|
||||
dy = 0;
|
||||
end
|
||||
end
|
||||
|
||||
if (display[2+2*x + dx, 2+2*y + dy] == CHAR_EMPTY) then
|
||||
switch(i)
|
||||
begin
|
||||
case 0:
|
||||
outf " X: ", x, " Y: ", y, " D: [UP]", "\r\n";
|
||||
end
|
||||
case 1:
|
||||
outf " X: ", x, " Y: ", y, " D: [DOWN]", "\r\n";
|
||||
end
|
||||
case 2:
|
||||
outf " X: ", x, " Y: ", y, " D: [LEFT]", "\r\n";
|
||||
end
|
||||
case 3:
|
||||
outf " X: ", x, " Y: ", y, " D: [RIGHT]", "\r\n";
|
||||
end
|
||||
end
|
||||
|
||||
DoTurn(x, y, dx, dy);
|
||||
|
||||
return true;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return false;
|
||||
end
|
||||
|
||||
bool TestField(int x, int y)
|
||||
var
|
||||
bool result;
|
||||
begin
|
||||
x = 2 + x*2;
|
||||
y = 2 + y*2;
|
||||
|
||||
result = true;
|
||||
|
||||
result &= (display[x, y] == CHAR_EMPTYFIELD);
|
||||
|
||||
result &= (display[x + 1, y] != CHAR_EMPTY);
|
||||
result &= (display[x - 1, y] != CHAR_EMPTY);
|
||||
result &= (display[x, y + 1] != CHAR_EMPTY);
|
||||
result &= (display[x, y - 1] != CHAR_EMPTY);
|
||||
|
||||
if (result) then
|
||||
display[x, y] = currplayer;
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
end
|
||||
end
|
||||
|
||||
void SwitchPlayer()
|
||||
begin
|
||||
if (currplayer == CHAR_PLAYER_P1) then
|
||||
currplayer = CHAR_PLAYER_P2;
|
||||
else
|
||||
currplayer = CHAR_PLAYER_P1;
|
||||
end
|
||||
|
||||
display[DISPLAY_WIDTH - 9, DISPLAY_HEIGHT - 1] = 'P';
|
||||
display[DISPLAY_WIDTH - 8, DISPLAY_HEIGHT - 1] = 'L';
|
||||
display[DISPLAY_WIDTH - 7, DISPLAY_HEIGHT - 1] = 'A';
|
||||
display[DISPLAY_WIDTH - 6, DISPLAY_HEIGHT - 1] = 'Y';
|
||||
display[DISPLAY_WIDTH - 5, DISPLAY_HEIGHT - 1] = 'E';
|
||||
display[DISPLAY_WIDTH - 4, DISPLAY_HEIGHT - 1] = 'R';
|
||||
display[DISPLAY_WIDTH - 3, DISPLAY_HEIGHT - 1] = ' ';
|
||||
display[DISPLAY_WIDTH - 2, DISPLAY_HEIGHT - 1] = currplayer;
|
||||
|
||||
display[1, DISPLAY_HEIGHT - 1] = (char)((p1_c/100)%10 + 48);
|
||||
display[2, DISPLAY_HEIGHT - 1] = (char)((p1_c/10)%10 + 48);
|
||||
display[3, DISPLAY_HEIGHT - 1] = (char)((p1_c/1)%10 + 48);
|
||||
display[4, DISPLAY_HEIGHT - 1] = ' ';
|
||||
display[5, DISPLAY_HEIGHT - 1] = '-';
|
||||
display[6, DISPLAY_HEIGHT - 1] = ' ';
|
||||
display[7, DISPLAY_HEIGHT - 1] = (char)((p2_c/100)%10 + 48);
|
||||
display[8, DISPLAY_HEIGHT - 1] = (char)((p2_c/10)%10 + 48);
|
||||
display[9, DISPLAY_HEIGHT - 1] = (char)((p2_c/1)%10 + 48);
|
||||
end
|
||||
|
||||
int GetSurrounding(int x, int y)
|
||||
var
|
||||
int result;
|
||||
begin
|
||||
result = 0;
|
||||
|
||||
x = 2 + x*2;
|
||||
y = 2 + y*2;
|
||||
|
||||
result += (int)(display[x + 1, y] != CHAR_EMPTY);
|
||||
result += (int)(display[x - 1, y] != CHAR_EMPTY);
|
||||
result += (int)(display[x, y + 1] != CHAR_EMPTY);
|
||||
result += (int)(display[x, y - 1] != CHAR_EMPTY);
|
||||
|
||||
return result;
|
||||
end
|
||||
|
||||
bool GameFinished()
|
||||
var
|
||||
int x, y;
|
||||
begin
|
||||
p1_c = 0;
|
||||
p2_c = 0;
|
||||
|
||||
for(x = 0; x < FIELD_WIDTH; x++) do
|
||||
for(y = 0; y < FIELD_HEIGHT; y++) do
|
||||
if (display[2+2*x, 2+2*y] == CHAR_PLAYER_P1) then
|
||||
p1_c++;
|
||||
elsif (display[2+2*x, 2+2*y] == CHAR_PLAYER_P2) then
|
||||
p2_c++;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return p1_c + p2_c == FIELD_WIDTH * FIELD_HEIGHT;
|
||||
end
|
||||
|
||||
char GetWinningPlayer()
|
||||
begin
|
||||
if (p1_c > p2_c) then
|
||||
return CHAR_PLAYER_P1;
|
||||
elsif (p1_c < p2_c) then
|
||||
return CHAR_PLAYER_P2;
|
||||
else
|
||||
return CHAR_PLAYER_NEUTRAL;
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
> **Note:** *This and other examples are included in the BefunGen download*
|
Loading…
Reference in New Issue
Block a user