如何在口齿不清中抽象出一个mancala板

时间:2013-10-24 06:21:34

标签: common-lisp

我正在尝试在Lisp中进行Mancala游戏。它将会有一个人工智能与人类玩家对战,但我被卡住了。我无法找到代表董事会的方式列表;我心中的主要问题是如何移动令牌。以下是how to play mancala

的参考资料

MANCALA BOARD

我正在考虑一个循环列表,但我找不到任何有关如何在Lisp中执行此操作的明确文档。

抱歉我的语法;英语不是我的母语。

3 个答案:

答案 0 :(得分:1)

现在我还没有阅读规则(对不起!)所以这只是为了解决使用循环数据结构的想法。

数据结构不必是循环的。只要你假装它会起作用! 阅读mod function

;;                      a1                  a6  b1                  b6
(defparameter *board* '(nil nil nil nil nil nil nil nil nil nil nil nil))

(defun wrap-position (pos) 
  (mod pos (length *board*)))

(defun push-token (position)
  (push t (nth (wrap-position position) *board*)))

(defun pull-token (position)
  (let ((contents (nth (wrap-position position) *board*)))
    (setf (nth (wrap-position position) *board*) (rest contents))))

(defun print-board ()
   (format t "| ~{~10<~a~>~} |~%| ~{~10<~a~>~} |" (reverse (subseq *board* 6)) 
                                                  (subseq *board* 0 6))
  *board*)

现在上面的技术是破坏性的。如果您还不知道lisp中的内容是谷歌还是在stackoveflow上搜索,那么有一些很好的描述。值得研究的是,你可能会发现你的AI想要“尝试”大量潜在的动作而“破坏”实际游戏 board ,非破坏性的方法可以帮助解决这个问题。现象书land of lisp有一些很好的信息。

这是一个简单的用法示例

CL-USER> *board*
(NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL)

CL-USER> (push-token 5)
(T)

CL-USER> *board*
(NIL NIL NIL NIL NIL (T) NIL NIL NIL NIL NIL NIL)

CL-USER> (push-token 5)
(T T)

CL-USER> *board*
(NIL NIL NIL NIL NIL (T T) NIL NIL NIL NIL NIL NIL)

CL-USER> (PULL-token 5)
(T)

CL-USER> *board*
(NIL NIL NIL NIL NIL (T) NIL NIL NIL NIL NIL NIL)

...I change the board before doing the next bit...

CL-USER> (print-board)
|        NIL       NIL       NIL       NIL       NIL       NIL |
|        NIL       NIL       NIL       NIL       NIL (T T T T) |

现在看看Sylwester的答案,看看你可以用一些石头替换子列表。您需要明显更改印刷板,但这样可以非常容易地操作非常简单的模型(几乎可以成为您需要的非破坏性步骤)。快去吧!

答案 1 :(得分:1)

我会使用14个fixnums的数组。指数0-5是A的坑,6是A的篮子。 7-12是球员B的坑,13是B的篮子。你用复制数组做minimax。

如果你想要列表,我可以单独使用A和B的列表,也可以将它们交错。你也可以只列出14个缺点。

答案 2 :(得分:0)

对不起,我真的不明白如何玩这个游戏,但是这里有一些我可以考虑的事情,如何去参加董事会:

(defstruct (mancala-cell
             (:print-object
              (lambda (cell stream)
                (format stream "<stones: ~d>"
                        (length (mancala-cell-stones cell))))))
  (stones nil :type list)
  (next nil))

(defun make-cells ()
  (labels ((%make-cells (head count)
             (let ((next (make-mancala-cell)))
               (setf (mancala-cell-next head) next)
               (if (> count 0) (%make-cells next (1- count)) next))))
    (let* ((first (make-mancala-cell))
           (last (%make-cells first 12)))
      (setf (mancala-cell-next last) first))))

(defstruct (mancala-board
             (:print-object
              (lambda (board stream)
                (loop :for i :from 0 :below 12
                   :for cell := (mancala-board-cells board)
                   :then (mancala-cell-next cell)
                   :do (princ (case i
                                (6 #\Newline) (0 "") (otherwise #\-))
                              stream)
                   (princ cell stream)))))
  (cells (make-cells) :type mancala-cell))

(print (make-mancala-board))
;; <stones: 0>-<stones: 0>-<stones: 0>-<stones: 0>-<stones: 0>-<stones: 0>
;; <stones: 0>-<stones: 0>-<stones: 0>-<stones: 0>-<stones: 0>-<stones: 0> 

然后是另外一个例子:

(defstruct (mancala-cell
             (:print-object
              (lambda (cell stream)
                (format stream "<stones: ~d>"
                        (mancala-cell-stones cell)))))
  (stones 4 :type fixnum))

(defconstant +null-cell+ (make-mancala-cell))

(deftype mancala-grid () '(array mancala-cell (12)))

(defun make-cells ()
  (loop
     :for i :from 0 :below 12
     :with result := (make-array
                      12 :element-type 'mancala-cell
                      :initial-element +null-cell+)
     :do (setf (aref result i) (make-mancala-cell))
     :finally (return result)))

(defstruct (mancala-board
             (:print-object
              (lambda (board stream)
                (loop :for i :from 0 :below 12
                   :for cell :across (mancala-board-cells board)
                   :do (princ (case i
                                (6 #\Newline) (0 "") (otherwise #\-))
                              stream)
                   (princ cell stream)))))
  (cells (make-cells) :type mancala-grid))

(defun map-cells-in-range (function board &key (start 0) (end 12))
  (loop
     :for i :from start :below end
     :with board := (mancala-board-cells board)
     :collect (funcall function (aref board (mod i 12)))))

(defun fold-cells-in-range (function board &key (start 0) (end 12))
  (loop
     :for i :from start :below (1- end)
     :with board := (mancala-board-cells board)
     :for cell := (aref board (mod i 12))
     :for result := (funcall
                     function
                     (aref board (mod i 12))
                     (aref board (mod (1+ i) 12)))
     :then (funcall function result (aref board (mod (1+ i) 12)))
     :finally (return result)))

(fold-cells-in-range
 (lambda (a b)
   (+ (mancala-cell-stones b)
      (if (integerp a) a (mancala-cell-stones a))))
 (make-mancala-board))                  ; 48