1
0

Updated BefunGen to >> BefunUtils

This commit is contained in:
2014-12-29 13:41:57 +01:00
parent 9ee572fa9f
commit 7500ee5b5a
25 changed files with 15 additions and 11 deletions

View File

@@ -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*

View File

@@ -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*

View File

@@ -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*

View File

@@ -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*

View File

@@ -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*

View 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*

View File

@@ -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*

View File

@@ -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*

View File

@@ -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*

View 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*

View File

@@ -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*