# The scripts in this tutorial implement the famous minesweeper game # STEP 7 class(minelabel,label) { mousePressEvent() { @$parent()->$mineLabelPressed($this,$0) } } class(minesweepermain,widget) { constructor($0 = rows,$1 = cols,$2 = num mines) { # We should check the parameters passed here, and maybe return 0 # if the params are not positive numbers echo $0,$1,$2 @%rows = $0 @%cols = $1 @%mines = $2 @%bGameRunning = 0 @%layout = $new(layout,$this) for(%i = 0;%i < @%rows;%i++) { for(%j = 0;%j < @%cols;%j++) { @%label{%i,%j}=$new(minelabel,$this,"%i_%j") @%label{%i,%j}->%row = %i @%label{%i,%j}->%col = %j @%label{%i,%j}->$setMinimumWidth(26) @%label{%i,%j}->$setMinimumHeight(26) @%label{%i,%j}->$setAlignment(HCenter , VCenter) @%layout->$addWidget(@%label{%i,%j},%i,%j) } } } newGame() { for(%i = 0;%i < @%rows;%i++) { for(%j = 0;%j < @%cols;%j++) { %l = @%label{%i,%j} %l->$setFrameStyle(Raised,WinPanel); %l->%bIsMine = 0 %l->%numMines = 0 %l->%bIsDiscovered = 0 %l->%iState = 0; # In state 0 it doesn't show anything %l->$setText("") %l->$setImage(); # show no image %l->$setEnabled(1) } } for(%i = 0;%i < @%mines;%i++) { %row = $rand($(@%rows - 1)) %col = $rand($(@%cols - 1)) while(@%label{%row,%col}->%bIsMine != 0) { %row = $rand($(@%rows - 1)) %col = $rand($(@%cols - 1)) } @%label{%row,%col}->%bIsMine = 1 if(%row > 0) { @%label{$(%row - 1),%col}->%numMines++ if(%col > 0)@%label{$(%row - 1),$(%col - 1)}->%numMines++ if(%col < (@%cols - 1))@%label{$(%row - 1),$(%col + 1)}->%numMines++ } if(%row < (@%rows - 1)) { @%label{$(%row + 1),%col}->%numMines++ if(%col > 0)@%label{$(%row + 1),$(%col - 1)}->%numMines++ if(%col < (@%cols - 1))@%label{$(%row + 1),$(%col + 1)}->%numMines++ } if(%col > 0)@%label{%row,$(%col - 1)}->%numMines++ if(%col < (@%cols - 1))@%label{%row,$(%col + 1)}->%numMines++ } @%bGameRunning = 1 # We keep track of the number of the discovered cells @%iTotalNonMineCells = $((@%rows * @%cols) - @%mines) @%iUndiscoveredNonMineCells = @%iTotalNonMineCells } mineLabelPressed($0 = mine label object that has been pressed,$1 = the button that has been pressed) { if(!@%bGameRunning)return if($1 == 1) { # Right button if($0->%bIsDiscovered)return; # does nothing switch($0->%iState) { case(0): { $0->$setImage(58) $0->%iState = 1 } case(1): { $0->$setImage(28) $0->%iState = 2 } case(2): { $0->$setImage() $0->%iState = 0 } } return; } if($0->%bIsMine) { @$gameFailure($0) } else { @$discoverCells($0) if(@%iUndiscoveredNonMineCells == 0) { # Finished! @$gameSuccess() } else { @$emit(userMoved) } } } discoverAllCells() { for(%i = 0;%i < @%rows;%i++) { for(%j = 0;%j < @%cols;%j++) { %l = @%label{%i,%j} if(!%l->%bIsDiscovered) { %l->$setFrameStyle(WinPanel,Sunken) if(%l->%bIsMine)%l->$setImage(82) else { %l->$setImage("") if(%l->%numMines > 0)%l->$setText(%l->%numMines) else %l->$setText("") } } %l->$setEnabled(0) } } } gameFailure($0 = the game cell that had the bomb) { @$discoverAllCells() $0->$setFrameStyle(WinPanel,Sunken) $0->$setImage(82); # 82 is a bomb $0->$setEnabled(1) @%bGameRunning = 0 @$emit(gameOver) } gameSuccess() { @$discoverAllCells() @%bGameRunning = 0 @$emit(success) } discoverCells($0 = mine label that has to be discovered) { if($0->%bIsMine)return; if($0->%bIsDiscovered)return; $0->%bIsDiscovered = 1 $0->$setFrameStyle(WinPanel,Sunken) @%iUndiscoveredNonMineCells-- if($0->%iState != 0)$0->$setImage(); # ensure that no image is shown if($0->%numMines > 0)$0->$setText($0->%numMines) else { if($0->%row > 0) { @$discoverCells(@%label{$($0->%row - 1),$0->%col}) if($0->%col > 0)@$discoverCells(@%label{$($0->%row - 1),$($0->%col - 1)}) if($0->%col < (@%cols - 1))@$discoverCells(@%label{$($0->%row - 1),$($0->%col + 1)}) } if($0->%row < (@%rows - 1)) { @$discoverCells(@%label{$($0->%row + 1),$0->%col}) if($0->%col > 0)@$discoverCells(@%label{$($0->%row + 1),$($0->%col - 1)}) if($0->%col < (@%cols - 1))@$discoverCells(@%label{$($0->%row + 1),$($0->%col + 1)}) } if($0->%col > 0)@$discoverCells(@%label{$0->%row,$($0->%col - 1)}) if($0->%col < (@%cols - 1))@$discoverCells(@%label{$0->%row,$($0->%col + 1)}) } } } class(minesweeper,window) { constructor() { @$setCaption("KVIrc's Minesweeper (0.1.0)"); @%layout = $new(layout,$$) @%menubar = $new(menubar,$$) @%menubar->$insertItem(test) @%layout->$addWidget(@%menubar,0,0) @%gamepool = $new(minesweepermain,$$,myGamepool,10,10,10) @%layout->$addWidget(@%gamepool,1,0) connect @%gamepool gameOver $$ gameOver # We connect the two new signals connect @%gamepool userMoved $$ showState connect @%gamepool success $$ success @%output = $new(label,$$) @%output->$setFrameStyle(WinPanel,Sunken) @%layout->$addWidget(@%output,2,0) @$newGame() } showState() { @%output->$setText("@%gamepool->%iUndiscoveredNonMineCells to go") } success() { @%output->$setText("You did it!") } gameOver() { @%output->$setText("Game Over :(") } newGame() { @%gamepool->$newGame() @%output->$setText("Ready") @$showState() } } %m = $new(minesweeper) %m->$show()