Vornweg: Ich weis, dass Minesweeper schon der Names eines Konkreten Spiels ist, aber ich weis nicht, ob es überhaupt ein wort für das spielgenre gibt.
BlitzMax: [AUSKLAPPEN] [EINKLAPPEN] SuperStrict
Type TMineField Field w:Int Field h:Int Field m:Int[,] Field known:Int[,] Field mines:Int Field dead:Int Method init(w:Int, h:Int, mines:Int) Self.w = w Self.h = h Self.mines = mines Self.m = New Int [w,h] Self.known = New Int [w,h] initField() End Method Method initField() For Local x:Int = 0 To w-1 For Local y:Int = 0 To h -1 m[x,y]=0 known[x,y]=0 Next Next For Local b:Int = 0 To mines -1 Local x:Int Local y:Int Repeat x = Rand(0,w-1) y = Rand(0,h-1) Until m[x,y]=0 m[x,y]=1 Next End Method Method debugPrint() Local str:String = " |"; Local str2:String = "-+"; For Local x:Int = 0 To w-1 str :+ x + " " str2:+ "--" Next Print str Print str2 For Local y:Int = 0 To h-1 Local str:String = ""; For Local x:Int = 0 To w-1 If known[x,y] If m[x,y] str :+ "*" Else str :+ getMinesAround(x,y) End If Else str :+ "?" End If str :+ " " Next Print y +"|"+str Next End Method Method getMinesAround:Int(x:Int,y:Int) Local ret:Int = 0; ret :+ checkMine(x-1,y-1) ret :+ checkMine(x ,y-1) ret :+ checkMine(x+1,y-1) ret :+ checkMine(x+1,y ) ret :+ checkMine(x+1,y+1) ret :+ checkMine(x ,y+1) ret :+ checkMine(x-1,y+1) ret :+ checkMine(x-1,y ) Return ret End Method Method checkMine:Int(x:Int, y:Int) If x<0 Return 0; If x>=w Return 0; If y<0 Return 0; If y>=h Return 0; Return m[x,y] End Method Method open(x:Int, y:Int) If x <0 Return If y <0 Return If x >= w Return If y >= h Return If known[x,y] Return; known[x,y] = 1 If m[x,y] dead=1; Return End If If Not getMinesAround(x,y) open(x-1,y) open(x+1,y) open(x,y-1) open(x,y+1) open(x-1,y-1) open(x-1,y+1) open(x+1,y-1) open(x+1,y+1) End If End Method End Type
Type TMineFieldDrawer Field mineField:TMineField; Field x:Int, y:Int, w:Int, h:Int; Method setMineField(mineField:TMineField) Self.mineField = mineField End Method Method setBounds(x:Int, y:Int, w:Int, h:Int) Self.x = x Self.y = y Self.w = w Self.h = h End Method Method draw() Local x:Int = Self.x Local y:Int = Self.y Local w:Int = Self.w Local h:Int = Self.h If w = 0 w = GraphicsWidth()-x If h = 0 h = GraphicsHeight()-y w:-1 h:-1 Local fieldw:Double = w/Double(mineField.w) Local fieldh:Double = h/Double(mineField.h) Local selectedx:Int; Local selectedy:Int; For Local fieldX:Int = 0 To mineField.w-1 For Local fieldY:Int = 0 To mineField.h-1 If Not minefield.known[fieldX,fieldY] SetColor 100,100,100 If MouseInRect(fieldw*fieldx, fieldh*fieldy, fieldw, fieldh) SetColor(200,200,200) selectedx = fieldX selectedy = fieldY End If DrawRect fieldW*fieldx, fieldh*fieldy, fieldw, fieldh ElseIf minefield.m[fieldX, fieldY] SetColor 255,0,0 DrawRect fieldW*fieldx, fieldh*fieldy, fieldw, fieldh Else SetColor 255,255,255 DrawRect fieldW*fieldx, fieldh*fieldy, fieldw, fieldh SetColor 0,0,0 Local i:Int = minefield.getMinesAround(fieldX, fieldY) If i DrawText i, fieldw*fieldx, fieldh*fieldy End If Next Next If MouseHit(1) And Not minefield.dead minefield.open(selectedx, selectedy) End If SetColor 0,0,0
For Local lx:Int = 0 To mineField.w Local dx:Int = (Double(w-x)/mineField.w)*lx DrawLine dx,y,dx,y+h Next For Local ly:Int = 0 To mineField.h Local dy:Int = (Double(h-y)/mineField.h)*ly DrawLine x,dy,x+w,dy Next End Method End Type
Function mouseInRect:Int(x:Int,y:Int,w:Int,h:Int) Return (MouseX()>x And MouseX() <= x+w And MouseY()>y And MouseY()<=y+h) End Function
;----------------------------------------- Graphics 800,600 SeedRnd(MilliSecs()) Local f:TMineField = New TMineField f.init(50,50,50) Local d:TMineFieldDrawer = New TMineFieldDrawer d.setMineField(f)
Repeat Cls If KeyHit(key_R) f.init(50,50,50) End If d.draw() Flip Until KeyHit(KEY_ESCAPE)
Interessant ist eigentlich nur der erste Type TMineField.
Diese Klasse kümmert sich nur um die Minesweeper-Logik, TMineFieldDrawer hab ich nur ganz rudimentär dazugehackt, um das ganze für die demonstration benutzbar zu machen.
Grüße,
Smily
|