2016-12-30 15 views
1

私はチェッカーのゲームのためにキャプチャ動作を試みるために、頂点とData.Mapを使用しています。私は、マップ内の現在のキーを更新するために関数changeKeyを使用しています。キャプチャ動作を行うにはcMove関数を使用しています。現在、cMoveは頂点、頂点のリスト(反対側のピースを含む)、頂点とブール値を含むマップを持ち、ピースがどのプレイヤーに属しているかを示します。 cMoveは、最初の頂点タプルがマップ内にあるかどうかをチェックします(計算が有効な移動の位置を検出すると、ボード上の位置が空であるかどうかを知るため)。そうであれば、changeKeyが呼び出されます。ここ辞書を再帰的にルーピングしてキーを削除する

changeKey :: (Integer, Integer) -> (Integer, Integer) -> Map (Integer, Integer) Bool -> Map (Integer, Integer) Bool 
changeKey k0 k1 myMap = case M.updateLookupWithKey (\_ _ -> Nothing) k0 myMap of 
     (Nothing, _ ) -> myMap 
     (Just e, myMap) -> M.insert k1 e myMap 

cMove :: (Integer, Integer) -> [(Integer, Integer)] -> Map (Integer, Integer) Bool -> Map (Integer, Integer) Bool 
cMove k [k1] myMap = if M.notMember (2*fst k1 - fst k, 2*snd k1 - snd k) myMap 
          then 
          changeKey k (2*fst k1 - fst k, 2*snd k1 - snd k) myMap 
          else myMap 

私の問題は、どのように私は頂点のリストをループすることができますし、プレイヤーがキャプチャを無制限に行うことができますよう、リストが(複数のタプルが含まれている場合、私は、暗闇にいるという事実にありますターン毎に)。さらに、対戦相手のピースを表す各キーが地図から削除されるようにするにはどうすればよいですか?

+1

あなたはこのように見える関数呼び出し使用することはできません: 'FST(K1)を'。代わりに、 '2 * fst k1 - fst k'のように' fst k1'だけを使うべきです。 –

+0

が編集されました。フィードバックをお寄せいただきありがとうございます。 –

+0

名前の綴りで判断すると、 'ChangeKey'は関数にすることはできません。 –

答えて

2

まず、the documentation for Data.Mapは、あなたのような状況でData.Mapの代わりにData.Map.Strictを使用することをお勧めします。

また、関数名は、通常、小文字で始まる必要があります。道のうちそれと


、ここでは繰り返しを行うための簡単な方法は、最終的な結果Mapfold the elements of a listにあります。 1回の反復処理を扱う関数を書くと(cMove'を参照)、すべての反復を行うにはfoldrまたはfoldl'のようなものを使用します。

私は次のようにあなたが望む行動を与えますが、ここでfoldrを使用して最初のドラフトだかはわからない:

import Data.Map.Strict (Map(..)) 
import qualified Data.Map.Strict as M 

changeKey :: (Integer, Integer) -> (Integer, Integer) -> Map (Integer, Integer) Bool -> Map (Integer, Integer) Bool 
changeKey k0 k1 myMap = case M.updateLookupWithKey (\_ _ -> Nothing) k0 myMap of 
     (Nothing, _ ) -> myMap 
     (Just e, myMap) -> M.insert k1 e myMap 

cMove :: (Integer, Integer) -> [(Integer, Integer)] -> Map (Integer, Integer) Bool -> Map (Integer, Integer) Bool 
cMove k ks myMap = foldr (cMove' k) myMap ks 
    where 
    cMove' :: (Integer, Integer) -> (Integer, Integer) -> Map (Integer, Integer) Bool -> Map (Integer, Integer) Bool 
    cMove' k k1 myMap = if M.notMember (2*fst k1 - fst k, 2*snd k1 - snd k) myMap 
           then changeKey k (2*fst k1 - fst k, 2*snd k1 - snd k) myMap 
           else myMap 
+0

そこに着いています。 1つの問題は、新しいkが残りのリストには使用されていないが、古いkはリストの残りの部分に使用されていないことです。明確にするために、changeKeyが呼び出されるたびに、cMoveは元の頂点の代わりに新しい頂点kを使用することになっています。 –

+0

リストが '[a、b、c、d、e]'ならば、最初に 'k'と' a'を使い、 'b'と' 3回目のC、などのように? –

関連する問題