N Queens Puzzle is a puzzle which asks you to place N chess queens on an NxN chess board so that no two queens are attacking each other. Two queens are attacking each other if they are on the same row, diagonal or column. I solved it using recursion in the dialect of AEC that's targeting WebAssembly. However, the dialect of AEC that's targeting x86 doesn't support custom functions (let alone recursion), so I cannot solve it the same way in it. So I solved it in the AEC dialect targeting x86 using stack instead of using recursion.
;A very advanced example: Solving the n-Queens Puzzle. ; https://flatassembler.github.io/nQueensPuzzle.html AsmStart macro pushIntegerToTheSystemStack x { sub esp,4 fld dword [x] fistp dword [esp] } macro pushPointerToTheSystemStack x { sub esp,4 lea ebx,[x] mov [esp],ebx } macro pushStringToTheSystemStack x { sub esp,4 mov dword [esp],x } format PE console entry start include 'win32a.inc' section '.text' code executable start: AsmEnd enterTheNumberString <= "Enter the number of queens.", 10, 0 floatSign <= "%f", 0 AsmStart pushPointerToTheSystemStack enterTheNumberString call [printf] add esp, 4 ;Cleaning up the system stack. When writing in assembly, there is no compiler to do that for you. pushPointerToTheSystemStack n pushPointerToTheSystemStack floatSign call [scanf] add esp, 8 AsmEnd topOfMyStack := 1 numberOfSolutions := 0 myStack[topOfMyStack * (n + 1)] := 0 While topOfMyStack > 0 howManyQueensAreOnTheBoard := myStack[topOfMyStack * (n + 1)] i := 0 While i < howManyQueensAreOnTheBoard queens[i] := myStack[topOfMyStack * (n + 1) + i + 1] i := i + 1 EndWhile topOfMyStack := topOfMyStack - 1 If howManyQueensAreOnTheBoard = n numberOfSolutions := numberOfSolutions + 1 i := 0 While i < n integerSignFollowedBySpace <= "%d ", 0 'A' + i ;The compiler will store this into the variable "result" AsmStart pushIntegerToTheSystemStack result call [putchar] add esp, 4 AsmEnd queens[i] + 1 AsmStart pushIntegerToTheSystemStack result pushPointerToTheSystemStack integerSignFollowedBySpace call [printf] add esp, 8 AsmEnd i := i + 1 EndWhile AsmStart pushPointerToTheSystemStack newLineString call [printf] add esp, 4 AsmEnd twoSpacesAndPlus <= " +",0 AsmStart pushPointerToTheSystemStack twoSpacesAndPlus call [printf] add esp, 4 AsmEnd column := 0 While column < n minusFollowedByPlus <= "-+", 0 AsmStart pushPointerToTheSystemStack minusFollowedByPlus call [printf] add esp, 4 AsmEnd column := column + 1 EndWhile AsmStart pushPointerToTheSystemStack newLineString call [printf] add esp, 4 AsmEnd row := n - 1 While row > 0 | row = 0 integerSignPrecededBySpace <= " %d",0 integerSign <= "%d",0 If row + 1 < 10 row + 1 AsmStart pushIntegerToTheSystemStack result pushPointerToTheSystemStack integerSignPrecededBySpace call [printf] add esp, 8 AsmEnd Else row + 1 AsmStart pushIntegerToTheSystemStack result pushPointerToTheSystemStack integerSign call [printf] add esp, 8 AsmEnd EndIf '|' AsmStart pushIntegerToTheSystemStack result call [putchar] add esp,4 AsmEnd column := 0 While column < n (queens[column] = row) ? 'Q' : (mod(row + column, 2) = 1) ? ' ' : '*' AsmStart pushIntegerToTheSystemStack result call [putchar] add esp, 4 AsmEnd '|' AsmStart pushIntegerToTheSystemStack result call [putchar] add esp,4 AsmEnd column := column + 1 EndWhile AsmStart pushPointerToTheSystemStack newLineString call [printf] add esp, 4 AsmEnd row := row - 1 column := 0 AsmStart pushPointerToTheSystemStack twoSpacesAndPlus call [printf] add esp, 4 AsmEnd While column < n AsmStart pushPointerToTheSystemStack minusFollowedByPlus call [printf] add esp, 4 AsmEnd column := column + 1 EndWhile AsmStart pushPointerToTheSystemStack newLineString call [printf] add esp, 4 AsmEnd EndWhile threeSpaces <= " ", 0 AsmStart pushPointerToTheSystemStack threeSpaces call [printf] add esp, 4 AsmEnd column := 0 While column < n 'A' + column AsmStart pushIntegerToTheSystemStack result call [putchar] add esp, 4 AsmEnd ' ' AsmStart pushIntegerToTheSystemStack result call [putchar] add esp, 4 AsmEnd column := column + 1 EndWhile AsmStart pushPointerToTheSystemStack newLineString call [printf] add esp, 4 AsmEnd Else rowOfTheQueenWeAreAboutToAdd := n - 1 columnOfTheQueenWeAreAboutToAdd := howManyQueensAreOnTheBoard While rowOfTheQueenWeAreAboutToAdd > 0 | rowOfTheQueenWeAreAboutToAdd = 0 isThereAQueenInTheSameRow := 0 i := 0 While i < howManyQueensAreOnTheBoard If queens[i] = rowOfTheQueenWeAreAboutToAdd isThereAQueenInTheSameRow := 1 EndIf i := i + 1 EndWhile isThereAQueenOnTheSameGlavnaDijagonala := 0 ;Sorry, I don't know how to say "glavna dijagonala" and "sporedna dijagonala" in English, and I am not wasting my time looking that up. i := 0 While i < howManyQueensAreOnTheBoard If queens[i] + i = rowOfTheQueenWeAreAboutToAdd + columnOfTheQueenWeAreAboutToAdd isThereAQueenOnTheSameGlavnaDijagonala := 1 EndIf i := i + 1 EndWhile isThereAQueenOnTheSameSporednaDijagonala := 0 i := 0 While i < howManyQueensAreOnTheBoard If queens[i] - i = rowOfTheQueenWeAreAboutToAdd - columnOfTheQueenWeAreAboutToAdd isThereAQueenOnTheSameSporednaDijagonala := 1 EndIf i := i + 1 EndWhile isThereAQueenOnTheSameDiagonal := isThereAQueenOnTheSameGlavnaDijagonala = 1 | isThereAQueenOnTheSameSporednaDijagonala = 1 If not(isThereAQueenInTheSameRow = 1) & not(isThereAQueenOnTheSameDiagonal = 1) topOfMyStack := topOfMyStack + 1 myStack[topOfMyStack * (n + 1)] := howManyQueensAreOnTheBoard + 1 i := 0 While i < howManyQueensAreOnTheBoard myStack[topOfMyStack * (n + 1) + i + 1] := queens[i] i := i + 1 EndWhile myStack[topOfMyStack * (n + 1) + howManyQueensAreOnTheBoard + 1] := rowOfTheQueenWeAreAboutToAdd EndIf rowOfTheQueenWeAreAboutToAdd := rowOfTheQueenWeAreAboutToAdd - 1 EndWhile EndIf EndWhile foundSolutionsString <= "Found %d solutions!", 10, 0 AsmStart pushIntegerToTheSystemStack numberOfSolutions pushPointerToTheSystemStack foundSolutionsString call [printf] add esp, 8 invoke system, _pause invoke exit, 0 _pause db "PAUSE",0 newLineString db 10,0 section '.rdata' readable writable result dd ? n dd ? myStack dd 1024 dup(?) queens dd 16 dup(?) topOfMyStack dd ? i dd ? numberOfSolutions dd ? howManyQueensAreOnTheBoard dd ? rowOfTheQueenWeAreAboutToAdd dd ? columnOfTheQueenWeAreAboutToAdd dd ? isThereAQueenInTheSameRow dd ? isThereAQueenOnTheSameGlavnaDijagonala dd ? isThereAQueenOnTheSameSporednaDijagonala dd ? isThereAQueenOnTheSameDiagonal dd ? row dd ? column dd ? section '.idata' data readable import library msvcrt,'msvcrt.dll' ;Microsoft Visual C Runtime Library (comes with Windows 98 and newer). import msvcrt,printf,'printf',system,'system',exit,'exit',scanf,'scanf',putchar,'putchar' AsmEnd
You have the .exe
file in this ZIP archive, it is called nQueensPuzzle.exe
.