⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 client.hpp

📁 本程序是主要是扫雷
💻 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 + -