Я делаю игру в крестики-нолики и составил протокол для своей стратегии. Игра работает нормально, поэтому я хочу воспользоваться этой возможностью, чтобы отточить свои навыки core.typed. Я аннотировал протокол (как показано ниже), но когда я запускаю (cf method-name)
или (cf protocol-name)
в ответе, я получаю эту ошибку:
eg:
=> `(cf win)`
clojure.lang.ExceptionInfo: Type Checker: Found 1 error :: {:type-error :top-level-error, :errors (#<ExceptionInfo clojure.lang.ExceptionInfo: Unannotated var tic-tac-toe.protocol/win
Hint: Add the annotation for tic-tac-toe.protocol/win via check-ns or cf {:env {:file "/Users/jessediaz/Documents/workspace/tic-tac-toe/src/tic_tac_toe/protocol.clj", :column 5, :line 47}, :form win, :type-error :clojure.core.typed.errors/tc-error-parent}>)}
Я проверил, чтобы убедиться, что версия протокола на самом деле является core.typed/protocol. Консоль рявкнула на меня, когда я использовал протокол>, говоря, что синтаксис устарел. Я также просмотрел документацию как на странице github, так и на clojure-doc.org. Так я узнал, что есть необязательное ключевое слово :methods
, которое я могу использовать для сопоставления методов с типами. Я чувствую, что это могло бы удалить много повторений из моего кода, но я не смог найти никаких примеров его использования. все основные методы стратегии в протоколе имеют побочные эффекты и возвращают nil
. Методы проверки либо возвращают nil
, либо исходные Strategy
методы, которые они проверяют. Я не уверен, что у меня правильный синтаксис, но код отлично оценивается в LightTable, с подписью Fn
или без нее, и вики core.typed подразумевает, что это не всегда необходимо.
Я чувствую, что нахожусь на пороге изучения этой удивительной библиотеки и был бы признателен за любой проницательный совет, который мог бы помочь моему пониманию.
файл протокола.clj:
(ns tic-tac-toe.protocol
(:require [clojure.core.typed :refer :all]))
(ann-protocol Strategy
win (Fn [Strategy -> nil])
block (Fn [Strategy -> nil])
fork (Fn [Strategy -> nil])
block-fork (Fn [Strategy -> nil])
take-center (Fn [Strategy -> nil])
take-opposite-corner (Fn [Strategy -> nil])
take-corner (Fn [Strategy -> nil])
take-side (Fn [Strategy -> nil])
can-win? (Fn [Strategy -> (U nil (Fn [Strategy -> nil]))])
can-block? (Fn [Strategy -> (U nil (Fn [Strategy -> nil]))])
can-fork? (Fn [Strategy -> (U nil (Fn [Strategy -> nil]))])
can-block-fork? (Fn [Strategy -> (U nil (Fn [Strategy -> nil]))])
can-take-center? (Fn [Strategy -> (U nil (Fn [Strategy -> nil]))])
can-take-corner? (Fn [Strategy -> (U nil (Fn [Strategy -> nil]))])
can-take-side? (Fn [Strategy -> (U nil (Fn [Strategy -> nil]))]))
(defprotocol Strategy
"Strategy methods update the Tic-tac-toe board when they are called"
;; strategies
(win [_] "wins the game by filling an open space to get 3 in a row")
(block [_] "blocks an opponents win by filling an open space")
(fork [_] "creates a two way win scenario guaranteeing victory")
(block-fork [_] "prevents an opponent from forking")
(take-center [_] "takes center")
(take-opposite-corner [_] "takes a corner opposite to one the computer already has")
(take-corner [_] "takes an avaiable corner")
(take-side [_] "takes an available side")
;; tests
(can-win? [_])
(can-block? [_])
(can-fork? [_])
(can-block-fork? [_])
(can-take-center? [_])
(can-take-opposite-corner? [_])
(can-take-corner? [_])
(can-take-side? [_]))