This repository has been archived on 2024-07-04. You can view files and clone it, but cannot push or open issues or pull requests.
khet/src/server.c

248 lines
5.3 KiB
C

/* -*- c-basic-offset: 4 -*- */
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include "net.h"
#include "game.h"
#include "asciiart.h"
#define MAX_MSG_LEN 50
/*
typedef enum { MSG_MOVE, MSG_ROTATE } message_type_t;
typedef struct {
message_type_t type;
union {
struct {
int row, col;
dir_t dir;
} move;
struct {
int row, col;
rot_t dir;
} rotate;
} args;
} message_t;
int
read_message(int side, message_t *m)
{
char buf[MAX_MSG_LEN+1];
char c;
int i;
for (i = 0; i < MAX_MSG_LEN+1; i++) {
c = net_getc(side);
printf("input '%c'\n", c);
if (c == '\n')
break;
buf[i] = c;
}
buf[i] = '\0';
while (c != '\n') c = net_getc(side);
switch (buf[0]) {
case 'M': m->type = MSG_MOVE; break;
case 'R': m->type = MSG_ROTATE; break;
default: return E_UNKNOWN_COMMAND;
}
if (m->type == MSG_MOVE) {
m->args.move.row = buf[2]-'A';
m->args.move.col = buf[3]-'0';
switch (buf[5]) {
case 'N':
m->args.move.dir = (buf[6]=='W' ? D_NW : (buf[6]=='E' ? D_NE : D_N));
break;
case 'S':
m->args.move.dir = (buf[6]=='W' ? D_SW : (buf[6]=='E' ? D_SE : D_S));
break;
case 'E':
m->args.move.dir = D_E;
break;
case 'W':
m->args.move.dir = D_W;
break;
}
net_all_printf("msg: MOVE (%d,%d) %d\n", m->args.move.row, m->args.move.col,
m->args.move.dir);
} else if (m->type == MSG_ROTATE) {
m->args.rotate.row = buf[2]-'A';
m->args.rotate.col = buf[3]-'0';
m->args.rotate.dir = (buf[5]=='L' ? R_CCW : R_CW);
}
return HUGE_SUCCESS;
}
int
execute_message(game_t *game, message_t msg, int side)
{
switch (msg.type) {
case MSG_MOVE:
return move(game, side,
msg.args.move.row, msg.args.move.col,
msg.args.move.dir, 0);
case MSG_ROTATE:
return rotate(game, side,
msg.args.rotate.row, msg.args.rotate.col,
msg.args.rotate.dir);
default:
net_side_printf(side, "unknown command type %d\n", msg.type);
return E_UNKNOWN_COMMAND;
}
}
*/
void
terminal_game(void)
{
game_t game;
move_t move;
char aabuf[ASCIIART_SMALL_BUFSZ];
char linebuf[10];
init_game(&game);
setup_board(&game, classic_setup);
asciiart_small_draw_board(aabuf, &game);
printf("%s", aabuf);
for (;;) {
printf("%s's move\n", sideinfo[game_turn(&game)].name);
fgets(linebuf, 10, stdin);
if (parse_move(linebuf, &move) != HUGE_SUCCESS) {
printf("not a valid move description: '%s'\n", linebuf);
continue;
}
if (perform_move(&game, game_turn(&game), move) != HUGE_SUCCESS) {
printf("invalid move\n");
continue;
}
if (game.last_move.type == M_ROTATE) {
printf("move: %c%c rotated %s\n",
game.last_move.y+'A',
game.last_move.x+'0',
game.last_move.dir==R_CW ? "R" : "L");
} else {
int nx, ny;
move_dest(game.last_move, &nx, &ny);
printf("move: %c%c moved to %c%c\n",
game.last_move.y+'A',
game.last_move.x+'0',
ny+'A', nx+'0');
}
if (game.last_hit.piece != NONE) {
printf("laser hits %s %s at %c%c\n",
sideinfo[game.last_hit.side].name,
pieceinfo[game.last_hit.piece].name,
game.laser_pos[1]+'A', game.laser_pos[0]+'0');
} else {
printf("laser hits wall at %c%c\n",
game.laser_pos[1]+'A', game.laser_pos[0]+'0');
}
asciiart_small_draw_board(aabuf, &game);
printf("%s", aabuf);
switch (game.winner) {
case SILVER:
printf("SILVER WINS!\n");
return;
case RED:
printf("RED WINS!\n");
return;
}
}
}
game_t game;
void
parse_line(int clientid, char *line) {
move_t move;
if (parse_move(line, &move) != HUGE_SUCCESS) {
net_client_printf(clientid, "not a valid move description: '%s'\n", line);
return;
}
if (perform_move(&game, clientid, move) != HUGE_SUCCESS) {
net_client_printf(clientid, "invalid move\n");
return;
}
if (game.last_move.type == M_ROTATE) {
net_all_printf("move: %c%c rotated %s\n",
game.last_move.y+'A',
game.last_move.x+'0',
game.last_move.dir==R_CW ? "R" : "L");
} else {
int nx, ny;
move_dest(game.last_move, &nx, &ny);
net_all_printf("move: %c%c moved to %c%c\n",
game.last_move.y+'A',
game.last_move.x+'0',
ny+'A', nx+'0');
}
if (game.last_hit.piece != NONE) {
net_all_printf("laser hits %s %s at %c%c\n",
sideinfo[game.last_hit.side].name,
pieceinfo[game.last_hit.piece].name,
game.laser_pos[1]+'A', game.laser_pos[0]+'0');
} else {
net_all_printf("laser hits wall at %c%c\n",
game.laser_pos[1]+'A', game.laser_pos[0]+'0');
}
char aabuf[ASCIIART_SMALL_BUFSZ];
asciiart_small_draw_board(aabuf, &game);
net_all_printf("%s", aabuf);
switch (game.winner) {
case SILVER:
net_all_printf("SILVER WINS!\n");
exit(0);
case RED:
net_all_printf("RED WINS!\n");
exit(0);
}
}
int player[2]={0, 0};
void
server_client_connect(int clientid) {
assert(clientid<2);
player[clientid]=1;
if (player[0] && player[1]) {
char aabuf[ASCIIART_SMALL_BUFSZ];
init_game(&game);
setup_board(&game, classic_setup);
asciiart_small_draw_board(aabuf, &game);
net_all_printf("%s", aabuf);
}
}
int
main(int argc, char **argv) {
if (argc > 1 && strcmp(argv[1], "local")==0) {
terminal_game();
return 0;
} else {
net_server(15239);
for (;;)
net_poll();
}
return 0;
}