2017-09-17 94 views
0

如何讓這種效率更高,以及如何在移動時保持網格不會斷裂。第一組代碼是批處理文件的設置,第二組是網格生成的一部分(我發現要長),第三組代碼是移動和顯示。4x4幻燈片拼圖BATCH

@echo off 
title Slide Puzzle && setlocal enabledelayedexpansion && set default= % 
set pos=16 
set loop=1 

以下是4x4網格中的第15個框。之前的那些並不長,但相同。它首先生成一個1到15之間的隨機數,並檢查它是否已被使用。在此之後,它會測試它是否是單個數字,如果它是單個數字,它會在它前面添加一個空格,以便它不會破壞網格。

有沒有辦法縮短這個?

:R15 
set /a R15=%random% %% 15 +1 
if %R15%==%R1% goto R15 
if %R15%==%R2% goto R15 
if %R15%==%R3% goto R15 
if %R15%==%R4% goto R15 
if %R15%==%R5% goto R15 
if %R15%==%R6% goto R15 
if %R15%==%R7% goto R15 
if %R15%==%R8% goto R15 
if %R15%==%R9% goto R15 
if %R15%==%R10% goto R15 
if %R15%==%R11% goto R15 
if %R15%==%R12% goto R15 
if %R15%==%R13% goto R15 
if %R15%==%R14% goto R15 
set slide15=%R15% 
if %R15% lss 10 set slide15= %R15% 

這就是數字顯示在4x4的方格

:display 
cls 
echo ____ ____ ____ ____ 
echo ^| ^| ^| ^| ^| 
echo ^| %slide1% ^| %slide2% ^| %slide3% ^| %slide4% ^| 
echo ^|____^|____^|____^|____^| 
echo ^| ^| ^| ^| ^| 
echo ^| %slide5% ^| %slide6% ^| %slide7% ^| %slide8% ^| 
echo ^|____^|____^|____^|____^| 
echo ^| ^| ^| ^| ^| 
echo ^| %slide9% ^| %slide10% ^| %slide11% ^| %slide12% ^| 
echo ^|____^|____^|____^|____^| 
echo ^| ^| ^| ^| ^| 
echo ^| %slide13% ^| %slide14% ^| %slide15% ^| %slide16% ^| 
echo ^|____^|____^|____^|____^| 

下面的一切,這是數字到側面如何移動到另一側及上下。這裏的問題是,如果您移動一個數字號碼,則會移除其中一個使網格不均勻和扭曲的空間。

:movew 
if %pos% GEQ 13 goto display 
set /a helper=%pos% + 4 
set /a slide%pos%=!slide%helper%! 
set slide%helper%=%default% 
set /a pos=%pos% + 4 
goto display 
:movea 
if %pos% == 4 goto display 
if %pos% == 8 goto display 
if %pos% == 12 goto display 
if %pos% == 16 goto display 
set /a helper=%pos% + 1 
set /a slide%pos%=!slide%helper%! 
set slide%helper%=%default% 
set /a pos=%pos% + 1 
goto display 
:moves 
if %pos% LEQ 4 goto display 
set /a helper=%pos% - 4 
set /a slide%pos%=!slide%helper%! 
set slide%helper%=%default% 
set /a pos=%pos% - 4 
goto display 
:moved 
if %pos% == 1 goto display 
if %pos% == 5 goto display 
if %pos% == 9 goto display 
if %pos% == 13 goto display 
set /a helper=%pos% - 1 
set /a slide%pos%=!slide%helper%! 
set slide%helper%=%default% 
set /a pos=%pos% - 1 
goto display 

回答

0

這裏的問題是,如果你移動一個它刪除的位數 使電網不均勻和扭曲的空間之一。

您應該移動恆定寬度的標籤字符串,而不是數字。

我能想到的多種策略用於消除標籤任何空格:

1)使用十六進制表示法:1 2 3 4 5 6 7 8 9 ABCDEF

2)使用0前綴:01 02 03 04 05 06 07 08 09 10 11 12 13 14 15
請注意,您不能將這些標籤用作數字,因爲0前綴數字被視爲八進制數字,08和09是無效的八進制數字。

3)使用字母:A B C d E F G H I J K L M N 2 O

不過應該沒有問題的空格操縱標籤。

它首先生成一個介於1到15之間的隨機數並檢查它是否已被使用。在此之後,它會測試它是否爲單個數字,如果它是 是一個數字,它會在它前面添加一個空格,以便它不會打破電網的 。

有沒有辦法縮短這個?

你隨機選擇1到15之間的數字,直到你得到一個沒有被使用過但非常低效的策略。理論上你可以等很久才能成功。只有15塊瓦片,等待時間可能不會很長,但如果您有數百種選擇要做,那麼您可能會等待一段時間。

更好地定義一個未使用的tile的字符串,然後隨機選擇一個字符串中的位置。分配選定的圖塊,然後從未使用的字符串中移除選定的圖塊。

@echo off 
setlocal enableDelayedExpansion 
cls 

:: Define string of equal width tile labels 
set "tiles= 1 2 3 4 5 6 7 8 9101112131415" 

:: Iterate and assign in reverse order so %%N matches the number of available unused tiles 
for /l %%N in (15 -1 1) do (

    %= Randomly select position of an unused tile, and compute the postion of next tile =% 
    set /a "selected=!random!%%%%N*2,next=selected+2" 

    %= Extract and assign the selected tile label =% 
    for %%A in (!selected!) do (
    set "slide%%N=!tiles:~%%A,2!" 

    %= Remove the selected tile from the list of unused tiles =% 
    for %%B in (!next!) do set "tiles=!tiles:~0,%%A!!tiles:~%%B! 
) 
) 

:: Show results 
set slide 


警告

我希望你明白,如果你隨機安排的瓷磚,你有機會50:50有一個無法解決的難題。 It is possible to compute if an arrangement is solvable。如果你的安排不可解決,那麼你應該能夠交換一對瓷磚來獲得可解決的難題。

+0

感謝您的非常詳細的回覆。 – Votex

2
:R15 
set /a R15=%random% %% 15 +1 
for /l %%n in (1,1,14) do if !R%%n! equ %R15% goto R15 
set slide15=%R15% 
if %R15% lss 10 set slide15= %R15% 
+0

這很有幫助 – Votex

0
:set_all_r 
for /L %%n in (1,1,16) do set /a R%%n=0 
set /a count=1 
:set_r 
set /a r!count!=%random% %% 15 + 1 
for /L %%n in (1,1,14) do if %%n neq %count% if !r%%n! equ !r%count%! goto set_r 
set slide%count%=!r%count%! 
if %count% lss 10 set "slide%count%= !r%count%!" 
set /a count+=1 
if %count% neq 16 goto set_r 
set "slide16= " 

此例程應該設置R *和滑動*
第一for套R *爲零;稍後分配非零值。

對於每個count,限制爲15(即直到遞增,結果爲16),設置一個隨機值並檢查沒有R *具有此值。如果發現一個具有相同的值,則重新選擇隨機值,否則增加計數直到達到限制。由於要分配的最後一個值是R15(R16 = 0,slide16 =「」,一個空的正方形),因此只需檢查R1..14。

((請不要接受這個答案是正確的 - 它只是一個開發上,通過@PaulHoule提交))