2

我正在尝试用 Lisp 制作Mancala游戏。它将有一个人工智能来与人类玩家对战,但我被困住了。我找不到将董事会表示为列表的方法;我心中的主要问题是如何移动代币。以下是如何玩曼卡拉的参考

曼卡拉板

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

对不起我的语法;英语不是我的母语。

4

3 回答 3

1

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

数据结构不必是循环的。只要你假装它是有效的!阅读mod 功能

;;                      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 中的内容,请在 google 或在 stackoveflow 上搜索,这里有一些很好的描述。值得研究一下,因为您可能会发现您的 AI 想要通过“破坏”实际游戏来“尝试”许多潜在动作,非破坏性方法可以帮助解决这个问题。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 的答案,看看你可以用一些石头替换子列表。您显然需要更改印刷板,但这为您提供了一个非常简单的模型,您可以非常轻松地操作(几乎可以是您制作非破坏性所需的重要步骤)。试试吧!

于 2013-10-24T06:57:09.627 回答
1

我会使用一个包含 14 个固定数字的数组。索引0-5是A的坑,6是A的篮子。7-12 是球员 B 的维修区,13 是 B 的篮筐。你用copy-array做minimax。

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

于 2013-10-24T11:44:57.487 回答
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
于 2013-10-24T08:01:54.450 回答