C++实现骑士走棋盘算法

本文实例为大家分享了C++实现骑士走棋盘算法的具体代码,供大家参考,具体内容如下

1.问题描述

骑士旅游Knight tour在十八世纪初倍受数学家与拼图迷的注意,它什么时候被提出已不可考,骑士的走法为西洋 棋的走法,骑士可以由任一个位置出发,它要如何走完所有的位置。

2.基本思路

骑士的走法,基本上可以用递回来解决,但是纯粹的递回在维度大时相当没有效率,一个聪明的解法由J.CWarnsdorff 在1823年提出, 简单地说,先将最难的位置走完,接下来的路就宽广了,骑士所想要的下一步,为下一不再 选 择时,所能走的步数最少的一步。使用这个方法,在不使用递回的情况下,可以有较高的机率找出走法(找不到走 的机率也是有的)

3.代码实现

#include <stdio.h>

int pos[8][8] = { 0 };

int travel(int, int);

int travel(int x, int y) {
 int i, j, k, l, m;
 int tmpX, tmpY;
 int count, min, tmp;

 //骑士可走的八个方向(顺时针)
 int ktmoveX[8] = { 1, 2, 2, 1, -1, -2, -2, -1 };
 int ktmoveY[8] = { -2, -1, 1, 2, 2, 1, -1, -2 };

 //测试下一步坐标
 int nextX[8] = { 0 };
 int nextY[8] = { 0 };

 //记录每个方向的出路的个数
 int exists[8] = { 0 };

 //起始用1标记位置
 i = x;
 j = y;
 pos[i][j] = 1;

 //遍历棋盘
 for (m = 2; m <= 64; m++) {
  //初始化八个方向出口个数
  for (l = 0; l < 8; l++) {
   exists[l] = 0;
  }
  l = 0; //计算可走方向

      //试探八个方向
  for (k = 0; k < 8; k++) {
   tmpX = i + ktmoveX[k];
   tmpY = j + ktmoveY[k];
   //边界 跳过
   if (tmpX < 0 || tmpY < 0 || tmpX>7 || tmpY>7) {
    continue;
   }
   //可走 记录
   if (pos[tmpX][tmpY] == 0) {
    nextX[l] = tmpX;
    nextY[l] = tmpY;
    l++;    //可走方向加1
   }
  }
  count = l;
  //无路可走 返回
  if (count == 0) {
   return 0;
   //一个方向可走 标记
  }
  else if (count == 1) {
   min = 0;
   //找出下个位置出路个数
  }
  else {
   for (l = 0; l < count; l++) {
    for (k = 0; k < 8; k++) {
     tmpX = nextX[l] + ktmoveX[k];
     tmpY = nextY[l] + ktmoveY[k];
     if (tmpX < 0 || tmpY < 0 || tmpX>7 || tmpY>7) {
      continue;
     }
     if (pos[tmpX][tmpY] == 0) {
      exists[l]++;
     }
    }
   }
   //找出下个位置出路最少的方向
   min = 0;
   tmp = exists[0];
   for (l = 0; l < count; l++) {
    if (exists[l] < tmp) {
     tmp = exists[l];
     min = l;
    }
   }
  }
  //用序号标记走过的位置
  i = nextX[min];
  j = nextY[min];
  pos[i][j] = m;
 }
 return 1;
}

int main()
{
 int i, j, startX, startY;
 while (1)
 {
  printf("输入起始点:");
  scanf("%d%d", &startX, &startY);
  if (travel(startX, startY)) {
   printf("游历完成!\n");
  }
  else {
   printf("游历失败!\n");
  }
  for (i = 0; i < 8; i++) {
   for (j = 0; j < 8; j++) {
    printf("%2d ", pos[i][j]);
   }
   printf("\n");
  }
  printf("\n");
 }

 return 0;
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • C++程序设计-五子棋

    前言:很多刚刚接触编程的人都不知道怎么下手编写程序,特别是学习了新的知识点,不知道有什么用,那么本文将以简单的存储结构及简单的运算,条件语句,分支语句,循环语句结合,带来一个双人对战版五子棋,这是一个简单的模型,实现了五子棋最最基本的功能,还有好多地方需要补全,如边界问题,设计问题,游戏逻辑问题,希望读者阅读后能够注意,通过自己的努力来完善它,还能扩展各种功能,如悔棋,网络对战等,有时候写程序和小生命一样,慢慢会成长,而我们作为"父母"的看到自己的小宝宝成为有用之才,过程之欣喜特别棒!

  • C++语言设计实现五子棋

    本文为大家分享了C++五子棋的设计思路和设计实现,供大家参考,具体内容如下 算法思路: 在结束了对C++的学习之后,准备自己编制一些简单的练习程序.目前初步设想是编制一个人机对战的简易五子棋软件. 以下为个人设计思考的过程. 首先,进行问题分析与设计.计划实现的功能为,开局选择人机或双人对战,确定之后比赛开始.比赛结束后初始化棋盘,询问是否继续比赛或退出.后续可加入复盘.悔棋等功能.整个过程中,涉及到了棋子和棋盘两种对象,同时要加上人机对弈时的AI对象,即涉及到三个对象. 棋盘类的设计. 数据存

  • 基于C++实现五子棋AI算法思想

    今天我想要分享一下我做五子棋AI的思路.因为在做这个之前,我没有接触过任何像这种类似的东西.通过这一次,我也算是有所了解,我的思路也是来自很多网络上的博客,看了很多,最终总结出了自己的这样一个. 那我的五子棋是15*15的大小(一般也就是这样的一个大小).我的AI算法要求每一次落子之后都要去计算每一个空暇的位置的"分值",简单的说,我们需要一个存放棋子的数组,表示是否存放了棋子,还要一个计算每一个空格的数组来记录"分数",这个分数是后期AI用来运算的基础,也是你AI

  • 基于c++ ege图形库实现五子棋游戏

    本文分享的五子棋实例,制作基于ege图像库, 首先需要安装配置ege环境 就可以编写小游戏了. 用到的ege库函数不多 , 主要是基于c++的. 先看界面效果: 输入界面:(就是控制台) 游戏胜利界面: 文档如下: 关于五子棋的构思: 实现人人对战的五子棋游戏.使用面向对象的c++ 和 ege库实现. ege的安装过程不在说明 , 在添加编译链接时去掉 -mwindows 选项. dev c++ 的运行环境设置为 TDM-GCC 4.8.1.32-bit Debug 为保险起见,编译时选择菜单栏

  • 基于C++和MFC开发象棋程序

    这是我要和大家分享的基于C++和MFC开发的一个象棋程序,目的是练习编程实践和大家分享同时希望大家能给出指教. 进入主题 一.棋盘分析 这是我绘制的棋盘,棋盘的组成由9条竖线和10条横线构成.这儿我们设置每条线间的间隔是50. 二.绘制过程 1.在vs中新建MFC程序,去除环境自动生成的按钮和文字. 2.打开***Dlg.cpp文件,在void CChessDlg::OnPaint()中定义一个棋盘间隔值和绘图设备CDC *cd = CWnd::GetDC(); int nWid = 50; C

  • 使用C++ MFC编写一个简单的五子棋游戏程序

    MFC简介: MFC(MicrosoftFoundationClasses)是微软基础类库的简称,是微软公司实现的一个c++类库,主要封装了大部分的windows API函数. MFC除了是一个类库以外,还是一个框架,在vc++里新建一个MFC的工程,开发环境会自动帮你产生许多文件,同时它使用了mfcxx.dll.xx是版本,它封装了mfc内核,所以你在你的代码看不到原本的SDK编程中的消息循环等等东西,因为MFC框架帮你封装好了,这样你就可以专心的考虑你程序的逻辑,而不是这些每次编程都要重复的

  • C++简单五子棋的AI设计实现

    本文实例为大家分享了C++五子棋的AI设计实现代码,供大家参考,具体内容如下 设计思路:通过接口获取信息来确定颜色,通过set_chess函数来确定落点. 对每个点位给出两种颜色棋子的打分,分别存在两个15*15的数组里,数组下标代表点的位置. 确定最大值所在数组之后,遍历该数组找出所有最大值对应的位置,然后对这些位置统计另一种颜色的棋子的分数,再选取一次最大值,从而确定要落点的位置. 打分函数的设计:在四个方向分别统计然后相加.对于某一个方向的分数统计,则分为正反两个方向进行,统计的时候如果有

  • C++实现五子棋游戏

    三子棋.五子棋之类的游戏,非常简单,对于初学者来说是一个不错的练手的小项目,以前用C语言写过三子棋游戏.最近在看C++,所以就想到在三子棋的基础上利用C++语言实现五子棋游戏. 主要功能: 有3个模式:0表示退出.1表示电脑vs玩家.2表示玩家vs玩家. 当一局完成之后选择'y'则又会进入选择模式. 源代码(VS2013编译器下写的): #include<iostream> #include<stdio.h> #include<stdlib.h> #include &l

  • C++面向对象实现五子棋小游戏

    尽量将面向对象的思想融入进程序中 ChessBoard.h //ChessBoard.h #pragma once #define ROW 15 #define COL 15 #include<iostream> using namespace std; class ChessBoard//棋盘类 { public: char m_cSquare[ROW][COL]; public: ChessBoard(); void show(); }; ChessBoard.cpp //ChessBoa

  • C++实现五子棋小程序

    这是一个用C++写的五子棋的小程序,关于A若是占据了已经下了的位置处理的不好.改动 hight,与width ,与q[][] 可以将棋盘扩大. #include<iostream> #include<vector> using namespace std; class qipan { public: qipan() {} ~qipan() {}; //向上下左右,斜的方向 char left(int x, int y) {//检查是否合适 if (x >= 1 &&a

随机推荐