rendered paste body/*
chess.c
A simple chess table. Needs rule checking and a better looking
'GUI' but its a start.
*/
// Base object
inherit BASE;
// Player whos turn it is, 0 - white, 1 - black
private nosave int pturn;
// Players
private nosave object white;
private nosave object black;
// The table display, only changes when the table changes.
nosave private string current_table;
// Inital stat of the table.
nosave private mixed array b = ({
({ "R","P","","","","","p","r" }),
({ "N","P","","","","","p","n" }),
({ "B","P","","","","","p","b" }),
({ "K","P","","","","","p","k" }),
({ "Q","P","","","","","p","q" }),
({ "B","P","","","","","p","b" }),
({ "N","P","","","","","p","n" }),
({ "R","P","","","","","p","r" })
});
// Prototype functions.
string compile_table();
string invalid_move(object p,int x1, int y1, int x2, int y2);
int move_piece(string arg);
int join_game(string side);
int part_game();
int player_index(object obj);
int same_color(string a, string b);
void create() {
if(!clonep()) {
return;
}
base::create();
pturn = 0;
set_id( ({ "table", "chess table" }) );
set_short( "a chess table" );
set_long( "\
This is a small chess table, thank Azhag.
chess display the current state of the chess table
join <color> join the <white> or <black> side
part leave the chess table
move FF TT where FF and TT are ordered pairs (XY)
Note: At the moment the table doenst check for valid moves
so you can move any piece anywhere. Just play by the rules
until I fix it.\n");
current_table = compile_table();
}
void init() {
add_action("move_piece", "place");
add_action("draw_table", "chess");
add_action("join_game", "join");
add_action("part_game", "part");
}
int draw_table() {
message("", current_table, this_player());
return 1;
}
string compile_table() {
int x,y;
string line;
string result;
result =
"White: " + (white ? white->query_name(1) : "") + "\n"+
"Black: " + (black ? black->query_name(1) : "") + "\n"+
"--It is " + ((pturn == 0) ? "White" : "Black") + "'s turn--\n\n";
for(y = 7; y >= 0; y--) {
line = y + " ";
for(x = 0; x < 8; x++) {
line += sprintf("%-1s ",((b[x][y] == "") ? "." : b[x][y]));
}
result += " "+line+"\n";
}
result += "\n 0 1 2 3 4 5 6 7\n\n--Chess table v0.1b--\n";
return result;
}
string invalid_move(object p,int x1, int y1, int x2, int y2) {
int calling_player = player_index(p) - 1;
if(pturn != calling_player) {
return "its not your turn";
}
if(b[x1][y1] == "") {
return "there is no piece at the source location "+x1+":"+y1;
}
if((x2 < 0 || x2 > 7) || (y2 < 0 || y2 > 7)) {
return "you cannot move a piece off the table.";
}
if((b[x1][y1] != "") && (b[x2][y2] !="")) {
if(same_color(b[x1][y1],b[x2][y2])) {
return "you cannot capture your own piece";
}
}
return;
}
int move_piece(string arg) {
int x1,y1;
int x2,y2;
string array args = explode(arg, " ");
string iv_move;
if(!player_index(this_player())) {
return notify_fail("You're not currently playing chess.\n");
}
if(sizeof(args) != 2) {
return notify_fail("move: invalid ordered pairs.\n");
}
if(strlen(args[0]) != 2) {
return notify_fail("move: ordered pair #1 is invalid.\n");
}
if(strlen(args[1]) != 2) {
return notify_fail("move: ordered pair #2 is invalid.\n");
}
x1 = atoi(args[0][0..0]); y1 = atoi(args[0][1..1]);
x2 = atoi(args[1][0..0]); y2 = atoi(args[1][1..1]);
iv_move = invalid_move(this_player(),x1,y1,x2,y2);
if(iv_move != "") {
return notify_fail("invalid move: "+iv_move+".\n");
}
(pturn == 0?pturn = 1:pturn = 0);
b[x2][y2] = b[x1][y1];
b[x1][y1] = "";
current_table = compile_table();
if(black) { message("",current_table,black); }
if(white) { message("",current_table,white); }
tell_room(environment(this_player()),
sprintf(this_player()->query_name()+" moves from %s to %s\n",
x1+":"+y1,x2+":"+y2),this_player());
return 1;
}
int join_game(string side) {
notify_fail("Syntax: join < white | black >\n");
if(player_index(this_player())) {
return notify_fail("You're already playing. You must part first.\n");
}
if(side == "white") {
if(!white) {
white = this_player();
current_table = compile_table();
message("",current_table,this_player());
tell_room(environment(this_player()),this_player()->query_name(1)+
" sits down on the white side of the chess table.\n",
this_player());
} else {
message("","Someone is already sitting there.\n",this_player());
}
} else if(side == "black") {
if(!black) {
black = this_player();
current_table = compile_table();
message("",current_table,this_player());
tell_room(environment(this_player()),this_player()->query_name(1)+
" sits down on the black side of the chess table.\n",
this_player());
} else {
message("","Someone is already sitting there.\n",this_player());
}
} else {
return 0;
}
return 1;
}
int part_game() {
int i = player_index(this_player());
if(i) {
if(i == 1) { white = 0; }
if(i == 2) { black = 0; }
message("","You are no longer playing chess.\n",this_player());
tell_room(environment(this_player()),this_player()->query_name(1)+
" stands up from the chess table.\n",this_player());
current_table = compile_table();
return 1;
}
}
int player_index(object obj) {
if(white == obj) { return 1; }
if(black == obj) { return 2; }
}
// Determine if a and b are the same case.
int same_color(string a, string b) {
int a_is_lower;
int b_is_lower;
a_is_lower = (a == lower_case(a)) ? 1 : 0;
b_is_lower = (b == lower_case(b)) ? 1 : 0;
return (a_is_lower == b_is_lower) ? 1 : 0;
}