Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

Connect 4 (4 gewinnt)


  • Please log in to reply
3 replies to this topic
pekoe
  • Members
  • 12 posts
  • Last active: Oct 23 2013 10:36 AM
  • Joined: 06 Sep 2008
; O = yellow stone, X = red stone

;--------------------------------------------------------------------------

; variables in this script

;--------------------------------------------------------------------------

; PositionLevel4Number321 = XO/O/X//OX// means:

; 1. column of the 321. position in the 4. level = XO

; 2. column = O

; 3. column = X

; The 4. column is empty.

; 5. column = OX

; The 6. and 7. column are empty.

;--------------------------------------------------------------------------

; ColorLevel4 = O means:

; In the 4. level it's O's turn.

;--------------------------------------------------------------------------

; ValueLevel4Number321 = 40 means:

; The value of the 321. position in the 4. level is 40.

; -999 = X has won

; 999 = O has won

;--------------------------------------------------------------------------

; ValuedLevel4Number321 = 0 means:

; The 321. position in the 4. level has not yet been valued.

; ValuedLevel4Number321 = 1 means:

; The 321. position in the 4. level has been valued.

;--------------------------------------------------------------------------

; BeforeLevel9Number876 = 543 means:

; The position before the 876. position in the 9. level was the

; 543. position in the 8. level.

;--------------------------------------------------------------------------

; PositionsLevel4 = number of positions in level 4

; PositionsLevel1 is always 1, PositionLevel1Number1 is the actual position.

;--------------------------------------------------------------------------



#NoEnv

#SingleInstance ignore

Gui, Font, s12, Arial

gui, add, button, ggo vgo, go!

gui, add, button, x+20 gback vback, back

Gui, Add, Checkbox, x+20 checked vAutoReply, auto-reply

Gui, Font, s12, Wingdings

loop, 7

{

	if a_index = 1

		gui, add, button, x15 w24 h24 gMyTurn vcolumn1, â

	else

		gui, add, button, xp+34 w24 h24 gMyTurn vcolumn%a_index%, â

}

Gui, Font, s14 cFFFFFF, Webdings

loop, 6

{

	a := (7 - a_index)

	loop, 7

	{

		b = %a_index%

		if b = 1

			gui, add, text, x18 vstone%b%%a%, n

		else

			gui, add, text, xp+34 vstone%b%%a%, n

	}

}

Gui, Font, s12 c000000, Arial

gui, add, text, x15 y+0, _________________________

gui, add, text, x15 w220 vInfo

gui, add, button, gnewgame vNewGame, new game

gui, add, DropDownList, x+20 r4 w80 vlevel, level 1|level 2|level 3||level 4

gui, show

PositionLevel1Number1 = //////

ColorLevel1 = O

PositionsLevel1 = 1

memory = //////

return



;__________________________________________________________________________



guiclose:

exitapp



;__________________________________________________________________________



newgame:

;--------------------------------------------------------------------------

; change PositionLevel1Number1

PositionLevel1Number1 = //////

;--------------------------------------------------------------------------

; change ColorLevel1

ColorLevel1 = O

;--------------------------------------------------------------------------

; change memory

memory = %memory%`n//////

;--------------------------------------------------------------------------

; change gui

Gui, Font, s12 norm, Wingdings

loop, 7

	GuiControl, Font, column%a_index%

i = 7

loop, 6

{

	i -= 1

	loop, 7

	{

		Gui, Font, s14 cFFFFFF, Webdings

		GuiControl, Font, stone%a_index%%i%

	}

}

GuiControl,, Info

return



;__________________________________________________________________________



go:

gui, submit, nohide

if level = level 1

	CalculateUpTo = 7

else if level = level 2

	CalculateUpTo = 49

else if level = level 3

	CalculateUpTo = 343

else if level = level 4

	CalculateUpTo = 2401

GuiControl, disable, go

GuiControl, disable, back

GuiControl, disable, AutoReply

GuiControl, disable, column1

GuiControl, disable, column2

GuiControl, disable, column3

GuiControl, disable, column4

GuiControl, disable, column5

GuiControl, disable, column6

GuiControl, disable, column7

GuiControl, disable, NewGame

GuiControl, disable, level

GuiControl,, Info, please wait ...

;--------------------------------------------------------------------------

; Calculate the positions of the 2. level from the actual position.

; Calculate the positions of the 3. level from the positions of the 2. level.

; etc.

;--------------------------------------------------------------------------

; levels

loop, 20

{

	lx = %a_index%

	ly := (lx + 1)

	if ColorLevel%lx% = O

		ColorLevel%ly% = X

	else

		ColorLevel%ly% = O

	ny = 0

;--------------------------------------------------------------------------

; positions

	loop, % PositionsLevel%lx%

	{

		nx = %a_index%

		ValueLevel%lx%Number%nx% := value(PositionLevel%lx%Number%nx%, 1)

		if (ValueLevel%lx%Number%nx% = 999 or ValueLevel%lx%Number%nx% = -999)

		{

			if lx = 2

			{

				before = %PositionLevel1Number1%

				PositionLevel1Number1 := PositionLevel2Number%nx%

				ColorLevel1 = %ColorLevel2%

				memory = %memory%`n%PositionLevel1Number1%

				goto ChangeGui

			}

			else

			{

				ValuedLevel%lx%Number%nx% = 1

				continue

			}

		}

;--------------------------------------------------------------------------

; columns

		loop, parse, PositionLevel%lx%Number%nx%, /

			column%a_index% = %A_LoopField%

		loop, 7

		{

			stringlen, l, column%a_index%

			if l = 6

				continue

			ny += 1

			ColumnRestore := column%a_index%

			NewStone := ColorLevel%lx%

			column%a_index% = %ColumnRestore%%NewStone%

;--------------------------------------------------------------------------

; new position

			PositionLevel%ly%Number%ny% = %column1%/%column2%/%column3%/%column4%/%column5%/%column6%/%column7%

			BeforeLevel%ly%Number%ny% = %nx%

			ValuedLevel%ly%Number%ny% =

;--------------------------------------------------------------------------

			column%a_index% = %ColumnRestore%

		}

	}

	PositionsLevel%ly% = %ny%

	if (PositionsLevel%ly% = 0 or PositionsLevel%ly% > CalculateUpTo)

		break

}

;--------------------------------------------------------------------------

; Value the positions of the last level.

; Deduce from these the values of the positions of the level before last.

; etc. up to the 2. level

; example:

; ValueLevel12Number1001 = 10

; ValueLevel12Number1002 = 0

; ValueLevel12Number1003 = -10

; The positions 1001 - 1003 in the 12. level are valued with 10, 0 and -10.

; BeforeLevel12Number1001 = 456

; BeforeLevel12Number1002 = 456

; BeforeLevel12Number1003 = 456

; The position before is the 456. position in the 11. level.

; ColorLevel11 = O

; It's O's turn.

; => ValueLevel11Number456 = ValueLevel12Number1001 = 10

; The value of the 456. position in the 11. level is 10,

; because the 1001. position in the 12. level is the best option for O.

;--------------------------------------------------------------------------

; game over?

if ly = 2

{

	GuiControl, enable, go

	GuiControl, enable, back

	GuiControl, enable, AutoReply

	GuiControl, enable, column1

	GuiControl, enable, column2

	GuiControl, enable, column3

	GuiControl, enable, column4

	GuiControl, enable, column5

	GuiControl, enable, column6

	GuiControl, enable, column7

	GuiControl, enable, NewGame

	GuiControl, enable, level

	if ValueLevel1Number1 = 999

		GuiControl,, Info, Yellow has won!

	else if ValueLevel1Number1 = -999

		GuiControl,, Info, Red has won!

	else

		GuiControl,, Info

	return

}

;--------------------------------------------------------------------------

; levels

loop, % (ly - 2)

{

;--------------------------------------------------------------------------

; positions

	loop, % PositionsLevel%ly%

	{

		ny = %a_index%

		nx := BeforeLevel%ly%Number%ny%

; if position ny in level ly is not yet valued

		if ValuedLevel%ly%Number%ny% <> 1

		{

; then value

			ValueLevel%ly%Number%ny% := value(PositionLevel%ly%Number%ny%, 0)

			ValuedLevel%ly%Number%ny% = 1

		}

; if position nx in level lx is not yet valued

		if ValuedLevel%lx%Number%nx% <> 1

		{

; then take the value from level ly

			ValueLevel%lx%Number%nx% := ValueLevel%ly%Number%ny%

			ValuedLevel%lx%Number%nx% = 1

		}

; else take the value from level ly only, if better

		else if (ColorLevel%lx% = "O" and ValueLevel%ly%Number%ny% > ValueLevel%lx%Number%nx%

		or ColorLevel%lx% = "X" and ValueLevel%ly%Number%ny% < ValueLevel%lx%Number%nx%)

			ValueLevel%lx%Number%nx% := ValueLevel%ly%Number%ny%

	}

	lx -= 1

	ly -= 1

}

;--------------------------------------------------------------------------

; If in the actual position it's O's turn, the position in the 2. level

; with the highest value is chosen.

; If in the actual position it's X's turn, the position in the 2. level

; with the lowest value is chosen.

;--------------------------------------------------------------------------

choose = 1

if ColorLevel1 = O

{

	loop, %PositionsLevel2%

	if (ValueLevel2Number%a_index% > ValueLevel2Number%choose%)

		choose = %a_index%

}

else if ColorLevel1 = X

{

	loop, %PositionsLevel2%

	if (ValueLevel2Number%a_index% < ValueLevel2Number%choose%)

		choose = %a_index%

}

;--------------------------------------------------------------------------

; change PositionLevel1Number1

before = %PositionLevel1Number1%

PositionLevel1Number1 := PositionLevel2Number%choose%

;--------------------------------------------------------------------------

; change ColorLevel1

ColorLevel1 = %ColorLevel2%

;--------------------------------------------------------------------------

; change memory

memory = %memory%`n%PositionLevel1Number1%

;--------------------------------------------------------------------------

ChangeGui:

Gui, Font, s12 norm, Wingdings

loop, 7

	GuiControl, Font, column%a_index%

loop, parse, PositionLevel1Number1, /

	column%a_index% = %A_LoopField%

loop, parse, before, /

	before%a_index% = %A_LoopField%

i = 7

loop, 6

{

	i -= 1

	loop, 7

	{

		stringmid, stone, column%a_index%, %i%, 1

		stringmid, before, before%a_index%, %i%, 1

		if (stone <> before)

		{

			Gui, Font, s12 bold, Wingdings

			GuiControl, Font, column%a_index%

			if stone = O

				Gui, Font, s14 cFFDD00 norm, Webdings

			else if stone = X

				Gui, Font, s14 cRed norm, Webdings

			GuiControl, Font, stone%a_index%%i%

		}

	}

}

GuiControl, enable, go

GuiControl, enable, back

GuiControl, enable, AutoReply

GuiControl, enable, column1

GuiControl, enable, column2

GuiControl, enable, column3

GuiControl, enable, column4

GuiControl, enable, column5

GuiControl, enable, column6

GuiControl, enable, column7

GuiControl, enable, NewGame

GuiControl, enable, level

GuiControl,, Info

return



;__________________________________________________________________________



back:

;--------------------------------------------------------------------------

; change memory

loop, parse, memory, `n

	CountLines = %a_index%

if CountLines = 1

	return

NewMemory =

loop, parse, memory, `n

{

	if a_index = %CountLines%

		break

	NewPosition = %A_LoopField%

	if NewMemory <>

		NewMemory = %NewMemory%`n

	NewMemory = %NewMemory%%A_LoopField%

}

memory = %NewMemory%

;--------------------------------------------------------------------------

; change PositionLevel1Number1

PositionLevel1Number1 = %NewPosition%

;--------------------------------------------------------------------------

; change ColorLevel1

stringlen, NewPositionLen, NewPosition

if mod(NewPositionLen, 2) = 0	; if as many O as X

	ColorLevel1 = O		; then it's O's turn

else

	ColorLevel1 = X

;--------------------------------------------------------------------------

; change gui

Gui, Font, s12 norm, Wingdings

loop, 7

	GuiControl, Font, column%a_index%

loop, parse, NewPosition, /

	column%a_index% = %A_LoopField%

i = 7

loop, 6

{

	i -= 1

	loop, 7

	{

		stringmid, stone, column%a_index%, %i%, 1

		if stone = O

			Gui, Font, s14 cFFDD00, Webdings

		else if stone = X

			Gui, Font, s14 cRed, Webdings

		else

			Gui, Font, s14 cFFFFFF, Webdings

		GuiControl, Font, stone%a_index%%i%

	}

}

GuiControl,, Info

return



;__________________________________________________________________________



MyTurn:

;--------------------------------------------------------------------------

; game over?

ValueLevel1Number1 := value(PositionLevel1Number1, 1)

if ValueLevel1Number1 = 999

{

	GuiControl,, Info, Yellow has won!

	return

}

else if ValueLevel1Number1 = -999

{

	GuiControl,, Info, Red has won!

	return

}

;--------------------------------------------------------------------------

; full column?

loop, parse, PositionLevel1Number1, /

	column%a_index% = %A_LoopField%

stringright, number, A_GuiControl, 1

stringlen, l, column%number%

if l = 6

	return

;--------------------------------------------------------------------------

; change gui

Gui, Font, s12 norm, Wingdings

loop, 7

	GuiControl, Font, column%a_index%

loop, 6

{

	stringmid, stone, column%number%, %a_index%, 1

	if stone =

	{

		if ColorLevel1 = O

		{

			Gui, Font, s14 cFFDD00, Webdings

			GuiControl, Font, stone%number%%a_index%

		}

		else if ColorLevel1 = X

		{

			Gui, Font, s14 cRed, Webdings

			GuiControl, Font, stone%number%%a_index%

		}

		break

	}

}

GuiControl,, Info

;--------------------------------------------------------------------------

; change PositionLevel1Number1

columnnumber := column%number%

column%number% = %columnnumber%%ColorLevel1%

PositionLevel1Number1 = %column1%/%column2%/%column3%/%column4%/%column5%/%column6%/%column7%

;--------------------------------------------------------------------------

; change ColorLevel1

if ColorLevel1 = O

	ColorLevel1 = X

else

	ColorLevel1 = O

;--------------------------------------------------------------------------

; change memory

memory = %memory%`n%PositionLevel1Number1%

;--------------------------------------------------------------------------

; go!

gui, submit, nohide

if AutoReply = 1

	gosub go

return



;__________________________________________________________________________



value(position, OnlyFour)

{

	loop, parse, position, /

	{

		x = %a_index%

		column = %A_LoopField%

		loop, 7

		{

			y = %a_index%

			stringmid, stone%x%%y%, column, %y%, 1

			if stone%x%%y% =

				stone%x%%y% = -

		}

	}

; __ horizontal rows

	row1 = %stone11%%stone21%%stone31%%stone41%%stone51%%stone61%%stone71%

	row2 = %stone12%%stone22%%stone32%%stone42%%stone52%%stone62%%stone72%

	row3 = %stone13%%stone23%%stone33%%stone43%%stone53%%stone63%%stone73%

	row4 = %stone14%%stone24%%stone34%%stone44%%stone54%%stone64%%stone74%

	row5 = %stone15%%stone25%%stone35%%stone45%%stone55%%stone65%%stone75%

	row6 = %stone16%%stone26%%stone36%%stone46%%stone56%%stone66%%stone76%

; | vertical rows

	row7 = %stone11%%stone12%%stone13%%stone14%%stone15%%stone16%

	row8 = %stone21%%stone22%%stone23%%stone24%%stone25%%stone26%

	row9 = %stone31%%stone32%%stone33%%stone34%%stone35%%stone36%

	row10 = %stone41%%stone42%%stone43%%stone44%%stone45%%stone46%

	row11 = %stone51%%stone52%%stone53%%stone54%%stone55%%stone56%

	row12 = %stone61%%stone62%%stone63%%stone64%%stone65%%stone66%

	row13 = %stone71%%stone72%%stone73%%stone74%%stone75%%stone76%

; / diagonal rows, min. 4 stones

	row14 = %stone13%%stone24%%stone35%%stone46%

	row15 = %stone12%%stone23%%stone34%%stone45%%stone56%

	row16 = %stone11%%stone22%%stone33%%stone44%%stone55%%stone66%

	row17 = %stone21%%stone32%%stone43%%stone54%%stone65%%stone76%

	row18 = %stone31%%stone42%%stone53%%stone64%%stone75%

	row19 = %stone41%%stone52%%stone63%%stone74%

; \ diagonal rows, min. 4 stones

	row20 = %stone14%%stone23%%stone32%%stone41%

	row21 = %stone15%%stone24%%stone33%%stone42%%stone51%

	row22 = %stone16%%stone25%%stone34%%stone43%%stone52%%stone61%

	row23 = %stone26%%stone35%%stone44%%stone53%%stone62%%stone71%

	row24 = %stone36%%stone45%%stone54%%stone63%%stone72%

	row25 = %stone46%%stone55%%stone64%%stone73%

	if OnlyFour = 1

	{

		loop, 25

		{

			ifinstring, row%a_index%, OOOO

				return 999

			ifinstring, row%a_index%, XXXX

				return -999

		}

	}

	else

	{

		b = 0

		loop, 25

		{

			ifinstring, row%a_index%, OOOO

				return 999

			ifinstring, row%a_index%, XXXX

				return -999

			ifinstring, row%a_index%, OOO-

				b += 40

			ifinstring, row%a_index%, OO-O

				b += 40

			ifinstring, row%a_index%, O-OO

				b += 40

			ifinstring, row%a_index%, -OOO

				b += 40

			ifinstring, row%a_index%, OO--

				b += 10

			ifinstring, row%a_index%, -OO-

				b += 10

			ifinstring, row%a_index%, --OO

				b += 10

			ifinstring, row%a_index%, O-O-

				b += 10

			ifinstring, row%a_index%, -O-O

				b += 10

			ifinstring, row%a_index%, O--O

				b += 10

			ifinstring, row%a_index%, XXX-

				b -= 40

			ifinstring, row%a_index%, XX-X

				b -= 40

			ifinstring, row%a_index%, X-XX

				b -= 40

			ifinstring, row%a_index%, -XXX

				b -= 40

			ifinstring, row%a_index%, XX--

				b -= 10

			ifinstring, row%a_index%, -XX-

				b -= 10

			ifinstring, row%a_index%, --XX

				b -= 10

			ifinstring, row%a_index%, X-X-

				b -= 10

			ifinstring, row%a_index%, -X-X

				b -= 10

			ifinstring, row%a_index%, X--X

				b -= 10

		}

		loop, 6

		{

			if stone2%a_index% = O

				b += 1

			if stone3%a_index% = O

				b += 2

			if stone4%a_index% = O

				b += 14

			if stone5%a_index% = O

				b += 2

			if stone6%a_index% = O

				b += 1

			if stone2%a_index% = X

				b -= 1

			if stone3%a_index% = X

				b -= 2

			if stone4%a_index% = X

				b -= 14

			if stone5%a_index% = X

				b -= 2

			if stone6%a_index% = X

				b -= 1

		}

		return %b%

	}

}


jaco0646
  • Moderators
  • 3165 posts
  • Last active: Apr 01 2014 01:46 AM
  • Joined: 07 Oct 2006
Wonderful! I love these kind of simple board games. If I may offer one suggestion: make the computer move automatically after every human move, to eliminate the Go button.

Kudos on offering multiple levels. That greatly increases the replay value. Out of curiosity, approximately how long did it take for you to code this game?

Thanks again! Keep up the good work!

pekoe
  • Members
  • 12 posts
  • Last active: Oct 23 2013 10:36 AM
  • Joined: 06 Sep 2008
New version with source code and GUI in English. Optionally moves automatically after every human move.

P1h3r1e3d13
  • Members
  • 4 posts
  • Last active: Sep 15 2008 11:52 PM
  • Joined: 09 Sep 2008
This is cool, thank you.

The back button switches sides.