Представляем версию игры Flip-Flop на поле 2x2, 4x4, 6x6, 8x8 написанную на Python с использованием библиотеки Tkinter. За Linux играет королевский пингвин, за FreeBSD - перец с трезубцем.

В этой игре ведут борьбу кнопки с логотипом пингвин, как известно, олицетворяющим OS Linux и кнопки с логотипом OS FreeBSD (красный перец с рожками и с трезубцем). На рис.1 представлены наши герои.

Рис. 1.

По правилам игры, игровое поле представляет собой квадрат разбитый на чётное количество клеток. Всё поле заполняется пингвинами и перцами в равных долях, но в случайном порядке. 

Цель игрока, нажимая на кнопки (клетки) на игровом поле, заполнить всё поле либо пингвинами, либо перцами. Когда игрок нажимает на клетку, картинка на ней инвертируется. Был перец — станет пингвин, был пингвин — станет перец.

Но не все так просто, игра усложняется тем, что одновременно с нажатой клеткой инвертируется весь ряд и вся колонка в которой находится эта клетка. Желаем удачи. 

#! /usr/bin/env python3
from tkinter import *
from  random import *
size = 4

tk = Tk()
Button(text='New Game').pack()
btn = list(Button() for i in range(size**2))
for i in btn: i.pack(expand=YES, fill=BOTH, side=LEFT)

mainloop()

Лист. 1. Программа.

Рис. 2. Игра Flip-Flop 4х4.

#! /usr/bin/env python3
from tkinter import *
from  random import *
size = 4

tk = Tk()
Button(text='New Game').pack()
frm = [Frame() for i in range(size)]
for i in frm: i.pack(expand=YES, fill=BOTH)
btn = list(Button(frm[i//size]) for i in range(size**2))
for i in btn: i.pack(expand=YES, fill=BOTH, side=LEFT)

mainloop()

Лист. 2. Программа.

Рис. 3. Игра Flip-Flop 4х4.

#! /usr/bin/env python3
from tkinter import *
from  random import *
size = 4

def play(i=-1):
    print(i)

tk = Tk()
Button(text='New Game', command = play).pack()
frm = [Frame() for i in range(size)]
for i in frm: i.pack(expand=YES, fill=BOTH)
btn = list(Button(frm[i//size], command = (lambda i=i: play(i))) for i in range(size**2))
for i in btn: i.pack(expand=YES, fill=BOTH, side=LEFT)

mainloop()

Лист. 3. Программа.

====== RESTART: ~/flip-flop.py ======
-1
0
1
2
3
4
5
14
15
>>>

Лист. 4. Вывод в командную строку.

#! /usr/bin/env python3
from tkinter import *
from  random import *
size = 4

def play(i=-1):
    if i == -1:
        playArea = [0]*(size**2//2) + [1]*(size**2//2) + ([0] if size**2%2 !=0 else [])
        print(playArea)
    else:
        print(i)

tk = Tk()
Button(text='New Game', command = play).pack()
frm = [Frame() for i in range(size)]
for i in frm: i.pack(expand=YES, fill=BOTH)
btn = list(Button(frm[i//size], command = (lambda i=i: play(i))) for i in range(size**2))
for i in btn: i.pack(expand=YES, fill=BOTH, side=LEFT)

mainloop()

Лист. 5. Программа.

====== RESTART: ~/flip-flop.py ======
[0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1]
0
1
2
13
14
15
>>>

Лист. 6. Вывод в командную строку.

#! /usr/bin/env python3
from tkinter import *
from  random import *
size = 4

def play(i=-1):
    global size, playArea
    if i == -1:
        playArea = [0]*(size**2//2) + [1]*(size**2//2) + ([0] if size**2%2 !=0 else [])
        shuffle(playArea)
        print(playArea)
    else:
        print(i)
    for i in range(0, size**2):
        btn[i].config(image=img[playArea[i]])

tk = Tk()
Button(text='New Game', command = play).pack()
frm = [Frame() for i in range(size)]
for i in frm: i.pack(expand=YES, fill=BOTH)
btn = list(Button(frm[i//size], command = (lambda i=i: play(i))) for i in range(size**2))
for i in btn: i.pack(expand=YES, fill=BOTH, side=LEFT)
img = [PhotoImage(file='PenguinLinux.png'), PhotoImage(file='FreeBSD.png')]
play()

mainloop()

Лист. 7. Программа.

====== RESTART: ~/flip-flop.py ======
[1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0]
[0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1]
1
5
6
10
15
[1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0]
>>>

Лист. 8. Вывод в командную строку.

Рис. 4. Игра Flip-Flop 4х4.

#! /usr/bin/env python3
from tkinter import *
from  random import *
size = 4

def play(i=-1):
    global size, playArea
    if i == -1:
        playArea = [0]*(size**2//2) + [1]*(size**2//2) + ([0] if size**2%2 !=0 else [])
        shuffle(playArea)
    else:
        if 1 in playArea and 0 in playArea:
            for j in range(i//size*size, i//size*size+size):
                playArea[j] = not(playArea[j])
            for j in range(i%size, size**2, size):
                playArea[j] = not(playArea[j])
            playArea[i] = not(playArea[i])
    for i in range(0, size**2):
        btn[i].config(image=img[playArea[i]])

tk = Tk()
Button(text='New Game', command = play).pack()
frm = [Frame() for i in range(size)]
for i in frm: i.pack(expand=YES, fill=BOTH)
btn = list(Button(frm[i//size], command = (lambda i=i: play(i))) for i in range(size**2))
for i in btn: i.pack(expand=YES, fill=BOTH, side=LEFT)
img = [PhotoImage(file='PenguinLinux.png'), PhotoImage(file='FreeBSD.png')]
play()

mainloop()

Лист. 9. Программа.

Рис. 5. Игра Flip-Flop 4х4.

#! /usr/bin/env python3
from tkinter import *
from  random import *
size = 4

def play(i=-1):
    global size, playArea, n
    if i == -1:
        n = 0
        tk.title('Linux or FreeBSD '+ str(size)+'x'+str(size))
        playArea = [0]*(size**2//2) + [1]*(size**2//2) + ([0] if size**2%2 !=0 else [])
        shuffle(playArea)
    else:
        if 1 in playArea and 0 in playArea:
            n += 1
            for j in range(i//size*size, i//size*size+size):
                playArea[j] = not(playArea[j])
            for j in range(i%size, size**2, size):
                playArea[j] = not(playArea[j])
            playArea[i] = not(playArea[i])
        if not(1 in playArea and 0 in playArea):            # Подумайте, почему нельзя else
            tk.title('You Win! ' + str(n) + ' moves')
    for i in range(0, size**2):
        btn[i].config(image=img[playArea[i]])

tk = Tk()
Button(text='New Game', command = play).pack()
frm = [Frame() for i in range(size)]
for i in frm: i.pack(expand=YES, fill=BOTH)
btn = list(Button(frm[i//size], command = (lambda i=i: play(i))) for i in range(size**2))
for i in btn: i.pack(expand=YES, fill=BOTH, side=LEFT)
img = [PhotoImage(file='PenguinLinux.png'), PhotoImage(file='FreeBSD.png')]
play()

mainloop()

Лист. 10. Программа.

Рис. 6. Игра Flip-Flop 4х4.

Рис. 7. Игра Flip-Flop 4х4.

#! /usr/bin/env python3
from tkinter import *
from  random import *
size = 4

def play(i=-1):
    global size, playArea, n
    if i == -1:
        n = 0
        tk.title('Linux or FreeBSD '+ str(size)+'x'+str(size))
        playArea = [0]*(size**2//2) + [1]*(size**2//2) + ([0] if size**2%2 !=0 else [])
        shuffle(playArea)
    else:
        if 1 in playArea and 0 in playArea:
            n += 1
            for j in range(i//size*size, i//size*size+size):
                playArea[j] = not(playArea[j])
            for j in range(i%size, size**2, size):
                playArea[j] = not(playArea[j])
            playArea[i] = not(playArea[i])
        if not(1 in playArea and 0 in playArea):            # Подумайте, почему нельзя else
            tk.title('You Win! ' + str(n) + ' moves')
    for i in range(0, size**2):
        btn[i].config(image=img[playArea[i]])

tk = Tk()
fr = Frame()
fr.pack()
Button(fr, text='2', command = play).pack(side=LEFT)
Button(fr, text='4', command = play).pack(side=LEFT)
Button(fr, text='New Game', command = play).pack(side=LEFT)
Button(fr, text='6', command = play).pack(side=LEFT)
Button(fr, text='8', command = play).pack(side=LEFT)
frm = [Frame() for i in range(size)]
for i in frm: i.pack(expand=YES, fill=BOTH)
btn = list(Button(frm[i//size], command = (lambda i=i: play(i))) for i in range(size**2))
for i in btn: i.pack(expand=YES, fill=BOTH, side=LEFT)
img = [PhotoImage(file='PenguinLinux.png'), PhotoImage(file='FreeBSD.png')]
play()

mainloop()

Лист. 11. Программа.

Рис. 8. Игра Flip-Flop 4х4.

#!/usr/bin/env python
# -*- Mode: Python; coding: utf-8; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- 
#
# LinuxORfreeBSD.py
# Copyright (C) 2021 Aleksandr Diorditsa, see <https://adior.ru>
# I want to thank all my students for the inspiration they give me.
#
# LinuxORfreeBSD.py is free software: you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# 
# LinuxORfreeBSD.py is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License along
# with this program.  If not, see <http://www.gnu.org/licenses/>.

from tkinter import *
from  random import *
size = 4
frm = []

def play(i=-1):
    global size, playArea, n, btn, frm
    if i < -1:
        size = abs(i)
        i = -1
    if i == -1:
        if len(frm)>0:
            for i in btn: i.destroy()
            for i in frm: i.destroy()
        n = 0
        tk.title('Linux or FreeBSD '+ str(size)+'x'+str(size))
        playArea = [0]*(size**2//2) + [1]*(size**2//2) + ([0] if size**2%2 !=0 else [])
        shuffle(playArea)
        frm = [Frame() for i in range(size)]
        for i in frm: i.pack(expand=YES, fill=BOTH)
        btn = list(Button(frm[i//size], command = (lambda i=i: play(i))) for i in range(size**2))
        for i in btn: i.pack(expand=YES, fill=BOTH, side=LEFT)
    else:
        if 1 in playArea and 0 in playArea:
            n += 1
            for j in range(i//size*size, i//size*size+size):
                playArea[j] = not(playArea[j])
            for j in range(i%size, size**2, size):
                playArea[j] = not(playArea[j])
            playArea[i] = not(playArea[i])
        if not(1 in playArea and 0 in playArea):            # Подумайте, почему нельзя else
            tk.title('You Win! ' + str(n) + ' moves')
    for i in range(0, size**2):
        btn[i].config(image=img[playArea[i]])

tk = Tk()
fr = Frame()
fr.pack()
Button(fr, text='2', command = (lambda: play(-2))).pack(side=LEFT)
Button(fr, text='4', command = (lambda: play(-4))).pack(side=LEFT)
Button(fr, text='New Game', command = play).pack(side=LEFT)
Button(fr, text='6', command = (lambda: play(-6))).pack(side=LEFT)
Button(fr, text='8', command = (lambda: play(-8))).pack(side=LEFT)
img = [PhotoImage(file='PenguinLinux.png'), PhotoImage(file='FreeBSD.png')]
play()

mainloop()

Лист. 12. Программа.

Рис. 9. Игра Flip-Flop 8х8.

#!/usr/bin/env python
# -*- Mode: Python; coding: utf-8; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- 
#
# LinuxORfreeBSD.py
# Copyright (C) 2021 Aleksandr Diorditsa, see <https://adior.ru>
# I want to thank all my students for the inspiration they give me.
#
# LinuxORfreeBSD.py is free software: you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# 
# LinuxORfreeBSD.py is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License along
# with this program.  If not, see <http://www.gnu.org/licenses/>.

from tkinter import *
from  random import *
size = 6                # Размер игрового поля

class FlipFlop():
    def __init__(self, tk, img, size):
        self.img = img
        self.tk = tk
        self.size = size
        frm = [Frame() for i in range(self.size)]
        for i in frm: i.pack(expand=YES, fill=BOTH)
        self.btn = [Button(frm[i//self.size], command = (lambda i=i: self.play(i))) for i in range(self.size**2)]
        for i in self.btn: i.pack(expand=YES, fill=BOTH, side=LEFT)
        self.newGame()
        
    def newGame(self, new=True):
        if new:
            self.tk.title('Linux or FreeBSD '+ str(self.size)+'x'+str(self.size))
            self.n = 0
            self.playArea = [0]*(self.size**2//2) + [1]*(self.size**2//2) + [0]
            shuffle(self.playArea)
        for i in range(0, self.size**2):
            self.btn[i].config(image=self.img[self.playArea[i]])
            
    def play(self, i):
        if 1 in self.playArea[0:self.size**2] and 0 in self.playArea[0:self.size**2]:
            self.n += 1
            for j in range(i//self.size*self.size, i//self.size*self.size+self.size):
                self.playArea[j] = not(self.playArea[j])
            for j in range(i%self.size, self.size**2, self.size):
                self.playArea[j] = not(self.playArea[j])
            self.playArea[i] = not(self.playArea[i])
            self.newGame(False)
        if not(1 in self.playArea[0:self.size**2] and 0 in self.playArea[0:self.size**2]):
            self.tk.title('You Win! ' + str(self.n) + ' moves')

tk = Tk()
img = [PhotoImage(file='PenguinLinux.png'), PhotoImage(file='FreeBSD.png')]
fifo = FlipFlop(tk, img, size)
Button(text='New Game', command = fifo.newGame).pack()

mainloop()

Лист. 14. Программа.

Рис. 10. Игра Flip-Flop 6x6.