Win2000的空当接龙算法

myblind 2005-03-07 04:30:19
加精
以下代码是反汇编 freecall 得到的代码。有需要的同志看看 :) 。
没有给出 -1 和 -2 局的算法,因为这两局是固定的,而且无解的牌局。

int gameNum = 1; // 牌局号
int cards[168], order[53];
int i,j,k;

for (i=0; i<168; i++)
cards[i] = -1;
for (i=0; i<=52; i++)
order[i] = i;

srand(gameNum);
for (i=0; i<52; i++)
{
j = rand() % order[52];
k = i/8 + (i & 7) * 21;
cards[k] = order[j];
order[j] = order[52-i-1];
--order[52];
}

for (i=0;i<168;i++)
{
if (cards[i] == -1)
printf("%-10d", -1);
else
{
k = ((cards[i]+1 % 13)+3) / 4;
k = k?k:13; // 计算牌面大小
printf("%-2d(%-2X) ", k, cards[i]);
}
}

牌的存储结构你可以通过打印出列表,对照着 freecall 游戏看的很清楚。

虽然得到了源代码,我却仍然不明白这样为什么会使牌局有解。:(
...全文
275 5 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
myblind 2005-03-09
  • 打赏
  • 举报
回复
楼上的是高人,那段算法我没有看明白,现在了解了.

有一个工具可以求解牌局,据作者说使用了 A* 算法. http://notabdc.vip.sina.com/index.htm 有
zengwujun 2005-03-08
  • 打赏
  • 举报
回复
mark
「已注销」 2005-03-08
  • 打赏
  • 举报
回复
我把你的算法整理了一下
1、压缩了放牌数组
2、去掉了取牌队列最后一个位置
3、明确了放牌是隔8个跳放
4、显示通用的牌名
5、算法更加明确化

各位可以执行时,设置gameNum,对照空当接龙的选局号码看结果

// freecell.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <stdlib.h>

int main(int argc, char* argv[])
{

int gameNum = 1; // 牌局号
int cards[64]; // 放牌牌局
int order[53]; // 取牌队列

int to; // 放牌位置
int from; // 取牌位置

int i;

char hand[5]="CDHS"; //花色:梅花,方片,红心,黑桃
char num[14]="A23456789TJQK"; //

for (i=0; i<52; i++) order[i] = i; // 顺序摆好取牌队列
for (i=0; i<8*8; i++) cards[i] = -1; // 清除放牌牌面

srand(gameNum); //选局的号码,rand 的种子

for (i=0; i<52; i++){
// 在当前的52-i的取牌队列中选一个位置 from 取牌
// 随机数求余数后,保证 from 落在队列中实际有牌的位置
from=rand() % (52-i);

// 由于采用横向放牌:实际上每隔8个位置放一张牌:0,8,16,24...56,1,9...
// 放牌牌局中位置to的值是i的低3位和高3位交换
to = (i & 070)>>3 | (i & 07) <<3;

// 取牌队列取第from个位置的牌 order[from],放入第to个位置 cards[to]
cards[to] = order[from];

// 第from个位置的牌 order[from],用最后一张牌order[52-i-1]补上,
// 保证取牌队列不出现空位
order[from] = order[52-i-1];

// 每显示8张牌,换下一行
if((i&7)==0) printf("\n");
// 显示这张牌是什么
printf("%c%c ", hand[cards[to]%4], num[cards[to]/4]);
// 显示取牌位置和放牌位置(调试用)
// printf("take %d to %d\n",from,to);
}

printf("\n");
getchar();
return 0;
}

结论:这个算法只是简单随机抽牌,按每行8个横向摆牌,
不能保证摆出的牌局一定有解。

我原以为可以根据放牌的神秘算法编出电脑解决算法,很郁闷。

请各位大侠指教电脑解法。



myblind 2005-03-08
  • 打赏
  • 举报
回复
可我觉的应该有什么原理, 要不作者为什么说"虽然没有验证过,但请相信所有牌局都可解". (也许他忘了 11982)
NowCan 2005-03-07
  • 打赏
  • 举报
回复
也不是都可解,11982就是无解.

33,027

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧