/* -*- c-basic-offset: 4 -*- */ #include #include #include "net.h" #include "game.h" pieceinfo_t pieceinfo[] = { { // NONE .num = 0, .name = "" }, { .num = 1, .name = "pharao" }, { // DJHED .num = 2, .name = "djhed" }, { // PYRAMID .num = 7, .name = "pyramid" }, { // OBELISK .num = 4, .name = "obelisk" }, { // OBELISK2 .num = 0, .name = "stacked obelisk" }, }; sideinfo_t sideinfo[] = { { .ch = '.', .name = "silver" }, { .ch = '=', .name = "red" } }; char classic_setup[] = "H40" // PHARAO "E40E51" // DJHED "H22G73E22D21E91D92C32" // PYRAMID "H30H30H50H50" // OBELISK ; int laser_at(game_t *game, int x, int y) { return game->laser_pos[0] == x && game->laser_pos[1] == y; } int laser(game_t *game, int side) { #define lreturn(v) do { retval=(v); goto ret; } while (0); int x, y, dir; int ddir; int retval; /* dir: 0 3 X 1 2 */ net_all_printf("LASER (%s)\n", sideinfo[side].name); assert(side == 0 || side == 1); switch (side) { case 0: x=9; y=7; dir=0; break; case 1: x=0; y=0; dir=2; break; } for (;;) { net_all_printf("pos: (%d,%d)\n", y, x); switch (game->board[x][y].piece) { case NONE: break; case PHARAO: game->last_hit = game->board[x][y]; lreturn(SILVER_WINS + 1-game->board[x][y].side); /* GAME OVER */ case OBELISK2: game->last_hit = game->board[x][y]; game->board[x][y].piece = OBELISK; lreturn(L_PIECE); case OBELISK: game->last_hit = game->board[x][y]; game->board[x][y].piece = NONE; lreturn(L_PIECE); case DJHED: ddir = (game->board[x][y].dir - dir) & 3; dir=(dir + 1 - 2*(ddir & 1)) & 3; break; case PYRAMID: ddir = (game->board[x][y].dir - dir) & 3; if (ddir & 2) { game->last_hit = game->board[x][y]; game->board[x][y].piece = NONE; lreturn(L_PIECE); } dir=(dir + 1 - 2*(ddir & 1)) & 3; break; } switch (dir & 3) { case 0: y--; if (y<0) lreturn(L_WALL); break; case 1: x++; if (x>BOARD_WIDTH-1) lreturn(L_WALL); break; case 2: y++; if (y>BOARD_HEIGHT-1) lreturn(L_WALL); break; case 3: x--; if (x<0) lreturn(L_WALL); break; } } ret: game->laser_pos[0] = x; game->laser_pos[1] = y; return retval; } int movable(game_t *game, int row, int col, int side) { return row>=0 && row=0 && colboard[col][row].piece != NONE && game->board[col][row].side == side; } int rotate(game_t *game, int side, int row, int col, rot_t dir) { int incr; if (!movable(game, row, col, side)) return E_ILLEGAL_MOVE; assert(dir==R_CW || dir==R_CCW); incr = dir==R_CW ? 1 : -1; game->board[col][row].dir = (game->board[col][row].dir + incr) & 3; return HUGE_SUCCESS; } int move(game_t *game, int side, int row, int col, int dir, int flags) { if (!movable(game, row, col, side)) return E_ILLEGAL_MOVE; /* dir = 0 1 2 7 X 3 6 5 4 */ assert((dir>=0) || (dir<=7)); int nrow = row - (dir<3) + ((dir>3) && (dir<7)); int ncol = col + ((dir>1) && (dir<5)) - ((dir<1) || (dir>5)); if ((ncol<0) || (ncol>9) || (nrow<0) || (nrow>7)) return E_ILLEGAL_MOVE; if (flags & F_SPLIT) { if (game->board[ncol][nrow].piece || (game->board[col][row].piece != OBELISK2)) return E_ILLEGAL_MOVE; game->board[col][row].piece = OBELISK; game->board[ncol][nrow].piece = OBELISK; game->board[ncol][nrow].side = game->board[col][row].side; return HUGE_SUCCESS; } if (game->board[ncol][nrow].piece && !((game->board[col][row].piece == DJHED) && ((game->board[ncol][nrow].piece != DJHED) && (game->board[ncol][nrow].piece != PHARAO)))) return E_ILLEGAL_MOVE; struct square tmp; tmp = game->board[ncol][nrow]; game->board[ncol][nrow] = game->board[col][row]; game->board[col][row] = tmp; return HUGE_SUCCESS; } void place(game_t *game, int row, int col, int piece, int side, int dir) { if (game->board[col][row].piece == OBELISK && game->board[col][row].side == side && piece == OBELISK) { piece = OBELISK2; } else if (game->board[col][row].piece != NONE && piece != NONE) { fprintf(stderr, "error: trying to place a piece on a non-empty square\n"); exit(EXIT_FAILURE); } game->board[col][row].piece = piece; game->board[col][row].side = side; game->board[col][row].dir = dir; } void clear_board(game_t *game) { int i, j; for (i = 0; i < BOARD_HEIGHT; i++) for (j = 0; j < BOARD_WIDTH; j++) place(game, i, j, 0, 0, 0); } void setup_board_place_piece(game_t *game, int piece, int side, char *place_desc) { int row, col, dir; row = place_desc[0]-'A'; col = place_desc[1]-'0'; dir = place_desc[2]-'0'; if (side == 1) { row = BOARD_HEIGHT-row-1; col = BOARD_WIDTH-col-1; dir = (dir+2)&3; } place(game, row, col, piece, side, dir); } void setup_board(game_t *game, char *desc) { int side, piece, num, i; clear_board(game); for (side = 0; side < 2; side++) { i = 0; for (piece = 0; piece < N_PIECE_TYPES; piece++) { for (num = 0; num < pieceinfo[piece].num; num++) { setup_board_place_piece(game, piece, side, &desc[i*3]); i++; } } } } void init_game(game_t *game) { game->move = 0; game->winner = -1; game->laser_pos[0] = game->laser_pos[1] = -1; clear_board(game); }