📄 client.hpp
字号:
/* Copyright(c) Ben Bear 2003-2004 */
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
// 02111-1307, USA.
#ifndef __client_hpp
#define __client_hpp
#include <string>
#include "info.hpp"
#include "checkers_client.hpp"
#include "client_connector.hpp"
#include "client_interface.hpp"
class client: public checkers_client, public client_con
{
protected:
client_interface scr_io;
unsigned int ip;
// show the chessboard, chesses and player's name
void show ();
void show_move (int s, int e);
void show_name (int p);
void show_chess (int h, int ch);
void show_jump (bool show);
void show_help (bool show);
void show_moved_chess ();
int turn_dir (int d);
int dir_back (int d);
// player to move a chess
bool player_move (int& s, int& e);
int player_step_move (int& s, int& e);
int player_direct_move (int& s, int& e);
bool join_game (const char* n);
bool wait_players ();
bool play ();
bool will_quit ();
public:
bool run (unsigned int i, const char* n);
};
bool
client::join_game (const char* name)
{
send_name (name);
int r = recv_int();
if (r == GAME_OVER)
return false;
int d;
setting set;
set.floor = recv_int();
set.number = recv_int();
set.long_jump = recv_bool();
set.group = recv_int();
set.stay_limit = recv_bool();
d = recv_int();
init (set, d, name);
send_int (ALL_OK);
return true;
}
bool
client::wait_players ()
{
int r;
// wait other players
do
{
r = recv_int ();
//fprintf (stderr, " :%d\n", r);
if (r == NEW_PLAYER)
{
int p = recv_int();
char p_name[PLAYER_NAME_LEN+1];
recv_name (p_name);
join_player (p, p_name);
//fprintf (stderr, "new player:%d:%s\n", p, p_name);
}
else if (r == PLAYER_QUIT)
{
int p = recv_int();
//fprintf (stderr, "player quit:%d\n", p);
quit_player (p);
}
if (will_quit())
{
//fprintf (stderr, "quit at wait_players\n");
send_int (PLAYER_QUIT);
return false;
}
send_int (ALL_OK);
show ();
}
while (r != GAME_START);
//send_int (ALL_OK);
return true;
}
bool
client::play ()
{
int r;
// oh, we play now
do
{
r = recv_int ();
if (r == ORDER_MOVE)
{
int s, e;
if (player_move (s, e) == false)
{
send_int (PLAYER_QUIT);
return false;
}
// send message of move a chess
send_int (MOVE_CHESS);
send_int (s);
send_int (e);
if (recv_int () == ALL_OK)
{
checkers_client::move (s, e);
show_move (s, e);
//show ();
}
else
{
show_chess (s, dir);
}
}
else if (r == MOVE_CHESS)
{
int s = recv_int();
int e = recv_int();
checkers_client::move (s, e);
show_move (s, e);
if (will_quit())
{
send_int (PLAYER_QUIT);
return false;
}
send_int (ALL_OK);
}
else if (r == GAME_OVER)
{
return false;
}
}
while (r != PLAYER_WIN);
return true;
}
bool
client::run (unsigned int i, const char* n)
{
ip = i;
if (client_con::connect (ip) == false)
{
return false;
}
//fprintf (stderr, "connected\n");
if (join_game (n) == false)
{
client_con::close ();
return false;
}
//fprintf (stderr, "joined\n");
scr_io.clear ();
show ();
if (wait_players () == false)
{
//fprintf (stderr, "close after wait_players\n");
client_con::close ();
return false;
}
//fprintf (stderr, "started\n");
show ();
bool result = play ();
scr_io.clear ();
scr_io.text_color (COLOR_TEXT);
if (result)
{
// the winner
int p = recv_int();
std::string str;
if ((p == dir) || is_group(p, dir))
{
if (group == 0)
str = "You win!";
else
str = "Your group win!";
}
else
{
str = "Player [ ";
for (int i = 0; i < 6; ++i)
if ((i == p) || is_group(p, i))
str += player[i].name + " ";
str += "] win!";
}
str += " \n";
scr_io.out_text (0, 0, str.c_str());
}
else
{
scr_io.out_text (0, 0,
"The game is over."
" May some one quit this game. \n");
}
client_con::close ();
return true;
}
void
client::show ()
{
scr_io.clear ();
for (int i = 0; i < 6; ++i)
{
if (player[i].end == -1)
continue;
show_name (i);
}
for (int i = 0; i < num_hole; ++i)
{
if (checkers_hole::in(floor, i) == false)
continue;
show_chess (i, holes[i]);
}
}
void
client::show_move (int s, int e)
{
show_chess (s, CHESS_NONE);//holes[s]);
show_chess (e, holes[e]);
}
void
client::show_name (int p)
{
int d = (p - dir + 7) % 6;
int g = p;
for (int i = 0; i < p; ++i)
if (is_group (p, i))
{
g = i;
break;
}
scr_io.show_name (d, g, player[p].name.c_str());
}
void
client::show_chess (int h, int ch)
{
if ((ch == CHESS_NONE) && checkers_hole::inside(floor, h))
ch = CHESS_INSIDE;
scr_io.show_chess (turn_dir(h), ch);
}
void
client::show_jump (bool show)
{
if (movable && (moved_chess != -1))
{
int h;
if (move_mode == STEP_MODE)
h = pos_chess;
else if (move_mode == DIRECT_MODE)
h = help_chess[pos_chess];
else
return;
int ch = (show ? CHESS_JUMP
: (move_mode == DIRECT_MODE) ? CHESS_HELP : CHESS_NONE);
show_chess (h, ch);
}
}
void
client::show_help (bool show)
{
if (help_len == -1)
return;
int ch = show ? CHESS_HELP : CHESS_NONE;
for (int i = 1; i < help_len; ++i)
show_chess (help_chess[i], ch);
if (move_mode == DIRECT_MODE)
{
ch = show ? CHESS_HELP : dir;
show_chess (help_chess[0], ch);
}
else if (help_len > 0)
show_chess (help_chess[0], ch);
}
void
client::show_moved_chess ()
{
show_chess (player[dir].chess[moved_chess], dir);
}
int
client::turn_dir (int d)
{
return honey_hole(d).turn(1 - dir);
}
int
client::dir_back (int d)
{
return (d + dir + 5) % 6;
}
bool
client::player_move (int& s, int& e)
{
//show ();
checkers_client::order_move();
int cmd;
choose_chess (0);
do
{
set_mode (STEP_MODE);
cmd = player_step_move (s, e);
if (cmd != KB_MODE)
continue;
set_mode (DIRECT_MODE);
cmd = player_direct_move (s, e);
}
while ((cmd != KB_FINISH) && (cmd != KB_QUIT));
checkers_client::finish_move();
scr_io.out_text (0, 0, " ");
//show ();
return cmd == KB_FINISH;
}
int
client::player_step_move (int& s, int& e)
{
assert (movable && (move_mode == STEP_MODE));
scr_io.out_text (0, 0, "MOVE: step ");
int cmd;
show_help (true);
show_jump (true);
do
{
cmd = scr_io.command ();
int d = 0;
switch (cmd)
{
case KB_UP:
case KB_DOWN:
{
int ch = (cmd == KB_DOWN) ? num_chess - 1 : 1;
ch = (ch + moved_chess) % num_chess;
show_jump (false);
show_help (false);
show_moved_chess ();
choose_chess (ch);
show_help (true);
show_jump (true);
break;
}
case KB_R_UP: ++d;
case KB_L_UP: ++d;
case KB_LEFT: ++d;
case KB_L_DOWN: ++d;
case KB_R_DOWN: ++d;
case KB_RIGHT:
{
int ch;
d = dir_back (d);
ch = search_jump (pos_chess, d);
if (ch == CHECKERS_HOLE_ERROR)
{
continue;
}
show_jump (false);
show_help (false);
move_step (ch);
show_help (true);
show_jump (true);
break;
}
case KB_QUIT:
case KB_MODE:
{
show_jump (false);
show_help (false);
return cmd;
break;
}
}
if ((cmd == KB_FINISH) && !in_stay(dir, pos_chess))
{
cmd = 0;
fputc ('\a', stderr);
}
}
while (cmd != KB_FINISH);
// || ((cmd == KB_FINISH) && !in_stay(dir, pos_chess)));
s = player[dir].chess[moved_chess];
e = pos_chess;
show_jump (false);
show_help (false);
return KB_FINISH;
}
int
client::player_direct_move (int& s, int& e)
{
int cmd;
scr_io.out_text (0, 0, "MOVE: direct ");
show_help (true);
show_jump (true);
do
{
cmd = scr_io.command ();
switch (cmd)
{
case KB_UP:
case KB_DOWN:
{
int ch = (cmd == KB_DOWN) ? num_chess - 1 : 1;
ch = (ch + moved_chess) % num_chess;
show_help (false);
show_moved_chess ();
choose_chess (ch);
show_help (true);
show_jump (true);
break;
}
case KB_LEFT:
case KB_RIGHT:
{
show_jump (false);
move_help (cmd == KB_RIGHT);
show_jump (true);
break;
}
case KB_QUIT:
case KB_MODE:
{
show_jump (false);
show_help (false);
return cmd;
break;
}
}
if ((cmd == KB_FINISH) && !in_stay(dir, help_chess[pos_chess]))
{
cmd = 0;
fputc ('\a', stderr);
}
}
while (cmd != KB_FINISH);
// && ((cmd == KB_FINISH) && !in_stay(dir, help_chess[pos_chess])));
s = player[dir].chess[moved_chess];
e = help_chess[pos_chess];
show_jump (false);
show_help (false);
return KB_FINISH;
}
bool
client::will_quit ()
{
return false;
if (scr_io.kbhit() && (scr_io.command() == KB_QUIT))
return true;
else
return false;
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -