Skip to content
Snippets Groups Projects
Commit 260d2812 authored by Benoît Harrault's avatar Benoît Harrault
Browse files

Add grid generator, upgrade grids templates

parent 6a5dea3a
No related branches found
No related tags found
1 merge request!8Resolve "Add more grids templates"
Pipeline #1385 passed
org.gradle.jvmargs=-Xmx1536M
android.useAndroidX=true
android.enableJetifier=true
app.versionName=0.0.7
app.versionCode=7
app.versionName=0.0.8
app.versionCode=8
......@@ -2,43 +2,78 @@
"templates": {
"2x2": {
"easy": [
"0000320400210100",
"0003034000040000",
"0402000000004020",
"0002001443002000",
"4312020000000020"
"0120040000010300",
"4000002030000401",
"4000030000010023",
"0100000410022300",
"0040000101343012",
"0000020334020000",
"0003130200200134",
"2000431000230000",
"0103304000000300",
"0043000000144030"
],
"medium": [
"3012200003000000",
"0003104030002100",
"0410100400000030",
"0100000030120000"
"4000010000010034",
"3002040100031300",
"4000000302000010",
"0100300000020043",
"0000004040013000",
"1003000420000000",
"1000000302300002",
"2001010400430000",
"0401200300004000",
"3004042000002000"
],
"hard": [
"0001000003000034",
"1000032000040002",
"0420000000100040",
"0300010010030240"
"0001000004200200",
"4030100000040000",
"0130021000002000",
"2000130000010020",
"0103300000010400",
"0000042000001004",
"0300000301044000",
"0001010002000003",
"0020020300010300",
"0410200010000200"
]
},
"3x3": {
"easy": [
"402370008801000000009086400108020000200060009000090207006450100000000603700032905",
"000100035060203000020059041002008304000000000509600700450320010000401070780005000",
"000130000070960050596000001000700105380000079704009000800000243040083010000091000",
"000300000001006030384200100700083056600000003830610002008005649060400200000002000"
"004210007090083010000500200007050831910600740400000000006100000801007450050300000",
"740150820562400070000000006308002000106040932090700605901830067680001000437690018",
"798413000340002809251800047003060092070000008519728030127650980900281670860907501",
"061030480300100000408060000009401008832070904100093056000009002903748001704052830",
"807625419000038602056090837729050060508061973103800500070902041081047296092316780",
"046000510815400039709060800074000208082541060053000104060014025091002300007093000",
"305000000009020600742301085918043500030107020407080019803710096674009132200406700",
"090002015165097040078450693802914000000005309000003081014529876580706132006130054",
"608010307070650800409008000000083600965074003300000072104500730806307200030020064",
"046050900000600700825010430002470085150809640000060000900238000038000120200190860"
],
"medium": [
"800050003004902700000340600305100800200030001001008409006093000003807200100060004",
"020000370500036029000200605004701006000000000600904100802009000950340007043000050",
"005060300091000005206400078000957010000000000080143000510004709900000620002030500",
"040006090080000320090570040005307900800090004009804200050089030073000010010700060"
"200960400006070900700000200000002040064090800002080307090000030038000502407100098",
"900500103010000005200001470825390604740000308000005702000219000060854020090063000",
"847300950900040003100008640004030001309804005000070406401785009000020004500000200",
"032070100048100090105300002001000050003000000200817400000783004000901000507426830",
"028000196506400700900816205069042000000078002702000000000591008100000000695004000",
"300000005006800100200005090002500000000107420718000003007008054460000200830640001",
"460100507915007000000000030000709002040000103000200050007024600000000780100675309",
"010039020000600041200000003360107002020003160000265370040076005100904700090010000",
"840063502100090003030702100204087300000420007080000009000076930050314200026000000",
"010805306004010800000000400057400008021073040040200710600000130000380004470026080"
],
"hard": [
"010900700050000060006207900600700080320804096080006007005602300060000010008003040",
"000009850900600402007050001000000093861000724730000000100020600406003009092800000",
"064900100000020006107006090000050364030000010576040000090500201700090000005007680",
"008007010512000370470051000000705900000010000004306000000560098045000763030900100"
"300089050520600007679150300000390804090068000700010005000071030000000000000935701",
"016007000000040105000000020023900046840000900607300010002501000008000600100639000",
"001800200089006050000053000600004700090070000007200809002700604000002100304000020",
"005000001000002598021000000009006003010000045000018700030049806407000000090760010",
"060000000058093000934080700002650007800900020400010008009307106000000080040009075",
"092500730030000900004930100008320506607050020300000000000005810500070009000208050",
"400063001008507000000900070300000910890070000106005004001600402000058036500400000",
"000007800004003000000000092000000184007009030810300059009034010400600020756190000",
"000003040009020078060700000952604000040210000000000900300500780090001060006002010",
"040070620300800904062000700407080000000615040056040000784060009600100070900000000"
]
}
}
......
#!/usr/bin/env bash
CURRENT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)"
ALLOWED_SIZE_VALUES="2 3"
ALLOWED_DIFFICULTY_VALUES="easy medium hard"
GRIDS_COUNT=10
for SIZE in ${ALLOWED_SIZE_VALUES}; do
echo "Size: ${SIZE}x${SIZE}"
for DIFFICULTY in ${ALLOWED_DIFFICULTY_VALUES}; do
echo "Difficulty: ${DIFFICULTY}"
for i in $(seq ${GRIDS_COUNT}); do
python ${CURRENT_DIR}/generate.py ${SIZE} ${DIFFICULTY} | tail -n 1
done
done
done
import sys
from random import randint, shuffle
if (len(sys.argv) != 3):
print('Usage: generate.py size difficulty')
print('size: [2|3]')
print('difficulty: [easy|medium|hard]')
exit()
size, difficulty = sys.argv[1], sys.argv[2]
size = int(size)
if not size in [2, 3]:
print('wrong size given')
exit()
if not difficulty in ['easy', 'medium', 'hard']:
print('wrong difficulty given')
exit()
############################################################################
# medium -> 5 (default) ; easy -> 1 ; hard -> 5
difficultyLevel = 5;
if difficulty == 'easy':
difficultyLevel = 1
if difficulty == 'hard':
difficultyLevel = 10
# draw grid (array style)
def drawGrid(grid):
for row in range(len(grid)):
for col in range(len(grid[row])):
if grid[row][col] != 0:
sys.stdout.write(str(grid[row][col]))
else:
sys.stdout.write(' ')
sys.stdout.write('\n')
sys.stdout.write('\n')
# draw grid (inline style)
def drawGridInline(grid):
for row in range(len(grid)):
for col in range(len(grid[row])):
sys.stdout.write(str(grid[row][col]))
sys.stdout.write('\n')
#initialise empty grid
def generateEmptyGrid(size):
emptyGrid = []
for i in range(size * size):
emptyGrid.append([])
for j in range(size * size):
emptyGrid[i].append(0)
return emptyGrid
#A check if the grid is full
def checkFullyCompletedGrid(grid):
for row in range(len(grid)):
for col in range(len(grid[row])):
if grid[row][col] == 0:
return False
return True
# (deep) copy of grid
def copyGrid(grid):
copiedGrid = []
for row in range(len(grid)):
copiedGrid.append([])
for col in range(len(grid[row])):
copiedGrid[row].append(grid[row][col])
return copiedGrid
#A backtracking/recursive function to check all possible combinations of numbers until a solution is found
def solveGrid(grid):
gridSize = len(grid)
cellsCount = len(grid) * len(grid[0])
numberList = [(value + 1) for value in range(gridSize)]
global solutionsCount
#Find next empty cell
for i in range(0, cellsCount):
row = i // gridSize
col = i % gridSize
if grid[row][col] == 0:
shuffle(numberList)
for value in numberList:
#Check that this value has not already be used on this row
if not(value in grid[row]):
#Check that this value has not already be used on this column
foundInColumn = False
for r in range(0, gridSize):
if (value == grid[r][col]):
foundInColumn = True
if not foundInColumn:
# Get sub-square
blockColFrom = size * int(col / size)
blockRowFrom = size * int(row / size)
square = [grid[i][blockColFrom:blockColFrom + size] for i in range(blockRowFrom, blockRowFrom + size)]
#Check that this value has not already be used on this sub square
if not any(value in squareLine for squareLine in square):
grid[row][col] = value
if checkFullyCompletedGrid(grid):
solutionsCount += 1
break
else:
if solveGrid(grid):
return True
break
grid[row][col] = 0
#A backtracking/recursive function to check all possible combinations of numbers until a solution is found
def fillGrid(grid):
gridSize = len(grid)
cellsCount = len(grid) * len(grid[0])
numberList = [(value + 1) for value in range(gridSize)]
global solutionsCount
#Find next empty cell
for i in range(0, cellsCount):
row = i // gridSize
col = i % gridSize
if grid[row][col] == 0:
shuffle(numberList)
for value in numberList:
#Check that this value has not already be used on this row
if not(value in grid[row]):
#Check that this value has not already be used on this column
foundInColumn = False
for r in range(0, gridSize):
if (value == grid[r][col]):
foundInColumn = True
if not foundInColumn:
# Get sub-square
blockColFrom = size * int(col / size)
blockRowFrom = size * int(row / size)
square = [grid[i][blockColFrom:blockColFrom + size] for i in range(blockRowFrom, blockRowFrom + size)]
#Check that this value has not already be used on this sub square
if not any(value in squareLine for squareLine in square):
grid[row][col] = value
if checkFullyCompletedGrid(grid):
return True
else:
if fillGrid(grid):
return True
break
grid[row][col] = 0
solutionsCount = 1
def computeResolvableGrid(grid, wantedAttempts):
gridSize = size * size
global solutionsCount
# A higher number of attempts will end up removing more numbers from the grid
# Potentially resulting in more difficiult grids to solve!
# Start Removing Numbers one by one
attempts = wantedAttempts
while attempts > 0:
# Select a random cell that is not already empty
row = randint(0, gridSize - 1)
col = randint(0, gridSize - 1)
while grid[row][col] == 0:
row = randint(0, gridSize - 1)
col = randint(0, gridSize - 1)
# Remove value in this random cell
savedCellValue = grid[row][col]
grid[row][col] = 0
solutionsCount = 0
solveGrid(copyGrid(grid))
# Non unique solution => restore this cell value
if solutionsCount != 1:
grid[row][col] = savedCellValue
attempts -= 1
grid = generateEmptyGrid(size)
sys.stdout.write('Solved grid:\n')
fillGrid(grid)
drawGrid(grid)
computeResolvableGrid(grid, difficultyLevel)
sys.stdout.write('Generated grid:\n')
drawGrid(grid)
sys.stdout.write('Inline grid:\n')
drawGridInline(grid)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment