平面ルービック

 投稿者:GAI  投稿日:2010年 7月16日(金)23時39分48秒
  ルービックキューブならぬ平面ルービックとでも名付けたい遊びで
初期条件(裏と表をランダムに設定)
から、任意の行もしくは列でひっくり返していき、最後に全各面が表(もしくは裏)
となるようにする。

(例)

                     ↓               ↓                    ↓
  →■□■   □■□   □■□ →□■□  ■□■   □□■   □□■   □□□
    □■■ →□■■   □□■   ■□■  ■□■   □□■   □□■   □□□
    ■■■   ■■■   ■■■   ■■■  ■■■ →□■■   □□■   □□□
      0       1       2       3      4       5       6       7

  これで遊べるプログラムをお願いしたい。
 

Re: 平面ルービック

 投稿者:山中和義  投稿日:2010年 7月17日(土)11時31分3秒
  > No.1301[元記事へ]

GAIさんへのお返事です。

CUIベースでつくってみました。LightOutのように攻略法はあるのですか?
LET M=3 !盤面の大きさ
LET N=3

DATA 1,0,1 !初期値
DATA 0,1,1
DATA 1,1,1

DIM B(M,N) !盤
MAT READ B

!!LET AA$="12A1A3C." !解 ※シミュレーション

DIM W(MAX(M,N))

LET S=1
DO !ゲームループ
   CALL PrintOut(B,M,N) !盤面の表示

   WHEN EXCEPTION IN

      PRINT S;"手目";
      INPUT A$
      !!LET A$=AA$(S:S) !解 ※シミュレーション
      !!PRINT "? "; A$  !解 ※シミュレーション

      IF A$="." THEN EXIT DO !ゲームオーバー、クリア

      LET t=fnVAL1(UCASE$(A$)) !選択された手に応じて
      IF t>=10 THEN !列
         LET t=t-9

         FOR i=1 TO M !列ベクトルを抽出する
            LET W(i)=B(i,t)
         NEXT i
         CALL reverse(W,M) !反転する
         FOR i=1 TO M !restore it
            LET B(i,t)=W(i)
         NEXT i

         LET S=S+1

      ELSE !行
         LET t=VAL(A$)

         FOR i=1 TO N
            LET W(i)=B(t,i)
         NEXT i
         CALL reverse(W,N)
         FOR i=1 TO N
            LET B(t,i)=W(i)
         NEXT i

         LET S=S+1

      END IF

   USE
      PRINT "正しい手を選択してください。"
      PRINT
   END WHEN
LOOP


END


EXTERNAL SUB PrintOut(B(,),M,N) !盤面を表示する
PRINT "   "; !列番号
FOR i=1 TO N
   PRINT " ";fnSTR1$(i+9);
NEXT i
PRINT
FOR i=1 TO M !表形式
   PRINT USING "##:": i; !行番号
   FOR j=1 TO N
      PRINT mid$("□■",B(i,j)+1,1); !復号化
   NEXT j
   PRINT
NEXT i
PRINT
END SUB

EXTERNAL SUB reverse(W(),N) !ビット位置とその値を反転させる
FOR i=1 TO INT(N/2)
   LET t=1-W(i) !swap it and bit-reverse
   LET W(i)=1-W(N-i+1)
   LET W(N-i+1)=t
NEXT i
IF MOD(N,2)=1 THEN LET W(INT(N/2)+1)=1-W(INT(N/2)+1)!center
END SUB


!N進法表記

EXTERNAL FUNCTION fnVAL1(x$) !1文字の数字を数値に変換する
LET fnVAL1=POS("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",x$)-1
END FUNCTION

EXTERNAL FUNCTION fnSTR1$(x) !1桁の数値を数字に変換する
LET fnSTR1$=MID$("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",x+1,1)
END FUNCTION

実行結果
    A B C
 1:■□■
 2:□■■
 3:■■■

 1 手目? 1
    A B C
 1:□■□
 2:□■■
 3:■■■

 2 手目? 2
    A B C
 1:□■□
 2:□□■
 3:■■■

 3 手目? a
    A B C
 1:□■□
 2:■□■
 3:■■■

 4 手目? 1
    A B C
 1:■□■
 2:■□■
 3:■■■

 5 手目? a
    A B C
 1:□□■
 2:□□■
 3:□■■

 6 手目? 3
    A B C
 1:□□■
 2:□□■
 3:□□■

 7 手目? c
    A B C
 1:□□□
 2:□□□
 3:□□□

 8 手目? .
 

Re: 平面ルービック

 投稿者:山中和義  投稿日:2010年 7月18日(日)14時17分29秒
  > No.1302[元記事へ]

GAIさんへのお返事です。

「裏表パズル」というのですね。


●いくつかの調査結果

盤面行列
 1,0,1 !初期値 ※0:□、1:■
 0,1,1
 1,1,1
に、判定行列
  1,0,-1
  0,0, 0
 -1,0, 1
の各要素ごとの積を計算して、その和は求める。
0の場合は、1色にできる。

掲載例は
 1*1+0*0+1*(-1) +0*0+1*0+1*0 +1*(-1)+1*0+1*1 = 0
より、可能。


また、最多手数は次の2つで(対称性を除く)、7手となる。

   □■□    ■□■
   ■■□    □■■
   □□□    ■■■
 

戻る