C语言编程技术:编程技术:如何创建一个简单的纸牌游戏

关于C语言编程技术的问题,在how to make a card game中经常遇到, 随着我学习 Ruby 语言,我越来越接近实际编程。我正在考虑创建一个简单的纸牌游戏。我的问题不是面向 Ruby 的,但我确实知道想学习如何用真正的 OOP 方法解决这个问题。

随着我学习 Ruby 语言,我越来越接近实际编程。我正在考虑创建一个简单的纸牌游戏。我的问题不是面向 Ruby 的,但我确实知道想学习如何用真正的 OOP 方法解决这个问题。

所以,我想知道的编程问题如下:

最终只能有唯一的值,所以选择随机值可能会产生重复。

我怎样才能实现一个简单的 AI?由于有大量的纸牌游戏,有人已经想通了这部分,所以参考将是巨大的。

我是一个真正的 Ruby nuby,我的目标是学习解决问题,所以伪代码将是伟大的,只是为了了解如何以编程方式解决问题。

此外,指向解释这些挑战的网站的指针将是一个很好的资源!

感谢您的评论,答案和反馈!

16

让你开始的东西

您可以使用从 0 到 51 的数字轻松确保唯一的卡。

Array#shuffle方法基于 Knuth-Fisher-Yates 洗牌算法。http://en..org/wiki/Fisher–Yates_shuffle

class Card
  RANKS = %w(2 3 4 5 6 7 8 9 10 J Q K A)
  SUITS = %w(Spade Heart Club Diamond)
  attr_accessor :rank, :suit
  def initialize(id)
    self.rank = RANKS[id % 13]
    self.suit = SUITS[id % 4]
  end
end
class Deck
  attr_accessor :cards
  def initialize
    # shuffle array and init each Card
    self.cards = (0..51).to_a.shuffle.collect { |id| Card.new(id) }
  end
end
# people with Ruby 1.9 (or 1.8.7 with backports) can safely ignore this duck punch
class Array
  # knuth-fisher-yates shuffle algorithm
  def shuffle!
    n = length
    for i in 0...n
      r = rand(n-i)+i
      self[r], self[i] = self[i], self[r]
    end
    self
  end
  def shuffle
    dup.shuffle!
  end
end

试验

d = Deck.new
d.cards.each do |card|
  puts "#{card.rank} #{card.suit}"
end

输出

6 Spade
5 Heart
2 Heart
8 Heart
8 Diamond
7 Club
J Diamond
4 Club
K Spade
5 Diamond
J Heart
8 Spade
10 Club
4 Diamond
9 Heart
7 Diamond
3 Diamond
K Diamond
7 Spade
Q Diamond
9 Diamond
6 Heart
A Heart
9 Club
A Spade
5 Club
J Club
Q Spade
2 Club
2 Spade
Q Heart
A Diamond
10 Spade
10 Diamond
Q Club
3 Club
A Club
K Club
6 Club
10 Heart
2 Diamond
3 Spade
K Heart
5 Spade
9 Spade
7 Heart
4 Spade
J Spade
3 Heart
4 Heart
8 Club
6 Diamond
5

Ruby 1.9 的原生Array#shuffle!Array#shuffle实际上使用了Knuth-Fisher-Yates shuffle algorithm

ruby-1.9.1-p376 / array.c

/*
 *  call-seq:
 *     array.shuffle!        -> array
 *  
 *  Shuffles elements in _self_ in place.
 */
static VALUE
rb_ary_shuffle_bang(VALUE ary)
{
    long i = RARRAY_LEN(ary);
    rb_ary_modify(ary);
    while (i) {
    long j = rb_genrand_real()*i;
    VALUE tmp = RARRAY_PTR(ary)[--i];
    RARRAY_PTR(ary)[i] = RARRAY_PTR(ary)[j];
    RARRAY_PTR(ary)[j] = tmp;
    }
    return ary;
}
/*
 *  call-seq:
 *     array.shuffle -> an_array
 *  
 *  Returns a new array with elements of this array shuffled.
 *     
 *     a = [ 1, 2, 3 ]           #=> [1, 2, 3]
 *     a.shuffle                 #=> [2, 3, 1]
 */
static VALUE
rb_ary_shuffle(VALUE ary)
{
    ary = rb_ary_dup(ary);
    rb_ary_shuffle_bang(ary);
    return ary;
}
3

不要费心寻找一个 AI 包

通过自己编码“AI”,您将了解更多并获得更大的满足感。

开始简单,只是考虑:

游戏状态-已经玩过或看过什么牌,所有玩家都可以看到什么牌

策略-计算机玩家如何根据其当前手牌和对游戏状态的了解做出反应

一旦你有了这个工作,你可以得到开发更复杂的策略:

inference-人类玩家根据她之前的动作可能持有什么牌

game tree search-考虑到可能发生的情况,如何最大化获胜的机会

然后,如果您想使真正复杂,则可以开始查看opponent modeling

2

Macek 的答案就设置甲板而言是好的。

您还询问了其他实体。

你可能想要四个“玩家”。每个玩家可能是人或机器控制的。

要实现一个人的球员,你的界面与屏幕 / 鼠标 / 键盘;实现机器控制的球员,你有一只手,你可以看到一些中央卡在桌子上(所有的球员需要知道的中央表,持有任何卡,将在桌子上)。

从那里的逻辑是基于你在玩什么游戏。

一旦你的“玩家”(AI)得到轮到(例如,一个takeTurn方法被调用你的玩家对象),它应该检查它的卡,并做出正确的决定-从桌上的堆叠卡或将卡从它的手放在桌子上。

当一个人类玩家调用他的takeTurn方法时,它应该与屏幕接口-更新玩家的手,允许他绘制和丢弃。

当每个玩家完成他的回合时,它应该返回。它不能直接调用下一个玩家(否则你会开始建立一个堆栈),所以你需要某种形式的回合控制,可以按顺序调用玩家。这种集中控制还可以防止玩家相互了解,他们不应该真正需要(最好的 OO 设计策略之一是每个对象应该尽可能少地了解其他对象)。

...还在想...我可能会添加更多...

本站系公益性非盈利分享网址,本文来自用户投稿,不代表码文网立场,如若转载,请注明出处

(58)
C 8 c 8:C# 8开关表达式(switch expression)
上一篇
C级护栏标准:C和 C++标准关于位级整数表示和操作说什么
下一篇

相关推荐

发表评论

登录 后才能评论

评论列表(41条)