Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdlib.h>
- #define EMPTY 0x00
- #define PLAYER 0x01
- #define BOX 0x02
- #define TARGET 0x04
- #define OUTSIDE 0xf0
- #define MATCH(x, bits) ((x & bits) == bits)
- #define AVAILABLE(x) (!MATCH(x, OUTSIDE) && !MATCH(x, BOX))
- #define MAX_WIDTH 10
- #define MAX_HEIGTH 10
- int WIDTH, HEIGTH;
- #define POS(x, y) (y * MAX_WIDTH + x)
- #define X(pos) (pos % MAX_WIDTH + 1)
- #define Y(pos) (pos / MAX_WIDTH + 1)
- #define END 987654321
- int posx, posy;
- int board[MAX_WIDTH + 4][MAX_HEIGTH + 4];
- void reset_board(int *boxes, int *targets, int *blocks) {
- int i, j, pos;
- for(i = 0; i < MAX_WIDTH+4; i++) {
- for(j = 0; j < MAX_HEIGTH+4; j++) {
- board[i][j] = OUTSIDE;
- if(2 <= i && i < WIDTH+2 && 2 <= j && j < HEIGTH+2) board[i][j] = EMPTY;
- }
- }
- for(i = 0; boxes[i] != END; i++) { int pos = boxes[i]; board[X(pos)][Y(pos)] = BOX; }
- for(i = 0; targets[i] != END; i++) { int pos = targets[i]; board[X(pos)][Y(pos)] |= TARGET; }
- for(i = 0; blocks[i] != END; i++) { int pos = blocks[i]; board[X(pos)][Y(pos)] |= OUTSIDE; }
- for(i = 2; i < WIDTH+2; i++) for(j = 2; j < HEIGTH+2; j++) {
- if(board[i][j] == EMPTY) { posx = i; posy = j; return; }
- }
- for(i = 2; i < WIDTH+2; i++) for(j = 2; j < HEIGTH+2; j++) {
- if(board[i][j] == TARGET) { posx = i; posy = j; return; }
- }
- fprintf(stderr, "no empty spaces!\n");
- exit(1);
- }
- int win_yet() {
- int i, j, tmp;
- for(j = 2; j < HEIGTH+2; j++) {
- for(i = 2; i < WIDTH+2; i++) {
- tmp = board[i][j];
- if(MATCH(tmp, TARGET) && !MATCH(tmp, BOX)) return 0;
- }
- }
- return 1;
- }
- #define OUTPUT(ch, attr) do { \
- if(attr != a) { printf("\x1b[%dm", attr); a = attr; } \
- printf("%c", ch); \
- } while(0)
- void draw_board() {
- int i, j, x;
- int a = 0, a_ = 0;
- OUTPUT('\r', 0); OUTPUT('\n', 0);
- for(j = 2; j < HEIGTH+2; j++) {
- OUTPUT(' ', 0);
- for(i = 2; i < WIDTH+2; i++) {
- x = board[i][j];
- if(i == posx && j == posy) OUTPUT('@', 36);
- else if(MATCH(x,OUTSIDE)) OUTPUT('=', 36);
- else if(MATCH(x, BOX)) OUTPUT('#', 33);
- else if(MATCH(x, TARGET)) OUTPUT('$', 35);
- else if(x == EMPTY) OUTPUT('.', 0);
- else OUTPUT('?', 41);
- }
- OUTPUT('\r', 0);
- OUTPUT('\n', 0);
- }
- return;
- }
- enum { North, South, East, West, Nowhere };
- void step(int x, int y, int dir) {
- int nx = x, ny = y;
- int nnx = x, nny = y;
- int t, s;
- if(dir == North) { ny--; nny -= 2; }
- if(dir == South) { ny++; nny += 2; }
- if(dir == East) { nx++; nnx += 2; }
- if(dir == West) { nx--; nnx -= 2; }
- t = board[nx][ny];
- s = board[nnx][nny];
- if(AVAILABLE(t)) { posx = nx; posy = ny; return; }
- if(MATCH(t, BOX) && AVAILABLE(s)) {
- t ^= BOX; board[nx][ny] = t;
- s ^= BOX; board[nnx][nny] = s;
- posx = nx; posy = ny; return;
- }
- return;
- }
- int main() {
- int boxes[] = { POS(3, 2), POS(4, 2), POS(2, 3), POS(2, 4), END };
- int targets[] = { POS(3, 3), POS(4, 3), POS(3, 4), POS(4, 4), END };
- int blocks[] = { END };
- WIDTH = 5;
- HEIGTH = 5;
- reset_board(boxes, targets, blocks);
- draw_board();
- int c = getc(stdin);
- while(c != EOF) {
- int dir = Nowhere;
- switch(c) {
- //case '\n': draw_board(); break;
- case '!': printf("goodbye\r\n"); exit(0); break;
- case 'q': printf("starting over...\r\n");
- reset_board(boxes, targets, blocks);
- break;
- default: printf("direction? [n, s, e, w]\r\n"); break;
- case 'n': case 'A': dir = North; break;
- case 's': case 'B': dir = South; break;
- case 'e': case 'C': dir = East; break;
- case 'w': case 'D': dir = West; break;
- };
- step(posx, posy, dir);
- if(win_yet()) {
- draw_board();
- printf("you win!\r\n");
- exit(0);
- }
- draw_board();
- c = getc(stdin);
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement