├── .gitignore ├── Project description.pdf ├── README.md ├── img ├── Airat_Bikbaev.JPG ├── Danil_Kashin.jpg ├── Yury_Kashnitsky.jpeg ├── faculty_logo.jpg ├── python_theme.png └── victims_predators.png ├── notebooks └── victims_predators_base.ipynb └── src └── victims_predators_base.py /.gitignore: -------------------------------------------------------------------------------- 1 | Thumbs.db 2 | 3 | # Byte-compiled / optimized / DLL files 4 | __pycache__/ 5 | *.py[cod] 6 | *$py.class 7 | 8 | # C extensions 9 | *.so 10 | 11 | # Distribution / packaging 12 | .Python 13 | env/ 14 | build/ 15 | develop-eggs/ 16 | dist/ 17 | downloads/ 18 | eggs/ 19 | .eggs/ 20 | lib/ 21 | lib64/ 22 | parts/ 23 | sdist/ 24 | var/ 25 | *.egg-info/ 26 | .installed.cfg 27 | *.egg 28 | 29 | # PyInstaller 30 | # Usually these files are written by a python script from a template 31 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 32 | *.manifest 33 | *.spec 34 | 35 | # Installer logs 36 | pip-log.txt 37 | pip-delete-this-directory.txt 38 | 39 | # Unit test / coverage reports 40 | htmlcov/ 41 | .tox/ 42 | .coverage 43 | .coverage.* 44 | .cache 45 | nosetests.xml 46 | coverage.xml 47 | *,cover 48 | .hypothesis/ 49 | 50 | # Translations 51 | *.mo 52 | *.pot 53 | 54 | # Django stuff: 55 | *.log 56 | local_settings.py 57 | 58 | # Flask stuff: 59 | instance/ 60 | .webassets-cache 61 | 62 | # Scrapy stuff: 63 | .scrapy 64 | 65 | # Sphinx documentation 66 | docs/_build/ 67 | 68 | # PyBuilder 69 | target/ 70 | 71 | # IPython Notebook 72 | .ipynb_checkpoints 73 | 74 | # pyenv 75 | .python-version 76 | 77 | # celery beat schedule file 78 | celerybeat-schedule 79 | 80 | # dotenv 81 | .env 82 | 83 | # virtualenv 84 | venv/ 85 | ENV/ 86 | 87 | # Spyder project settings 88 | .spyderproject 89 | 90 | # Rope project settings 91 | .ropeproject 92 | -------------------------------------------------------------------------------- /Project description.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yorko/one_cool_programming_task/5acb1ad9be9de1fbf99ff59bda1d4e43a9dc920d/Project description.pdf -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Бодрый командный проект по программированию на языке Python. Задача «Закон джунглей» 2 | 3 | ## Задача 4 | Напишите программу, моделирующую экологическую систему океана, в котором обитают хищники :crocodile: и жертвы :fish:. Океан представляется двуxмерным массивом ячеек. В ячейке может находиться либо хищник, либо жертва, либо препятствие. В каждый квант времени ячейки последовательно обрабатываются. Хищник может съесть соседнюю жертву или просто переместиться на соседнюю клетку, добыча также может переместиться на соседнюю клетку. Если в течение некоторого времени хищник ничего не съел, он погибает. Через определенные интервалы времени хищники и жертвы размножаются, если рядом есть свободная ячейка. При этом потомок занимает свободную ячейку. 5 | 6 | Текущее состояние экрана отображается на экране, желательно в виде графического интерфейса. Моделирование закачивается либо по истечении некоторого числа итераций, либо когда погибнут все хищники или жертвы. 7 | 8 | Проверьте на этой модели гипотезу о цикличности популяций хищников и жертв. 9 | 10 | ## В этом репозитории: 11 | - Project description.pdf - еще раз описание задачи 12 | - notebooks - начало решения в виде тетрадки Jupyter 13 | - src - начало решения в виде .py файла 14 | - img - подгружайте сюда свои фотографии, познакомимся :smile: 15 | -------------------------------------------------------------------------------- /img/Airat_Bikbaev.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yorko/one_cool_programming_task/5acb1ad9be9de1fbf99ff59bda1d4e43a9dc920d/img/Airat_Bikbaev.JPG -------------------------------------------------------------------------------- /img/Danil_Kashin.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yorko/one_cool_programming_task/5acb1ad9be9de1fbf99ff59bda1d4e43a9dc920d/img/Danil_Kashin.jpg -------------------------------------------------------------------------------- /img/Yury_Kashnitsky.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yorko/one_cool_programming_task/5acb1ad9be9de1fbf99ff59bda1d4e43a9dc920d/img/Yury_Kashnitsky.jpeg -------------------------------------------------------------------------------- /img/faculty_logo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yorko/one_cool_programming_task/5acb1ad9be9de1fbf99ff59bda1d4e43a9dc920d/img/faculty_logo.jpg -------------------------------------------------------------------------------- /img/python_theme.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yorko/one_cool_programming_task/5acb1ad9be9de1fbf99ff59bda1d4e43a9dc920d/img/python_theme.png -------------------------------------------------------------------------------- /img/victims_predators.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yorko/one_cool_programming_task/5acb1ad9be9de1fbf99ff59bda1d4e43a9dc920d/img/victims_predators.png -------------------------------------------------------------------------------- /notebooks/victims_predators_base.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "
\n", 8 | "\n", 9 | "# Майнор \"Интеллектуальный анализ данных\" \n", 10 | "# Курс \"Введение в программирование\"\n", 11 | "\n", 12 | "\n", 13 | "## Автор материала: Юрий Кашницкий, ФКН НИУ ВШЭ\n", 14 | "
\n", 15 | "Материал распространяется на условиях лицензии Ms-RL. Можно использовать в любых целях, кроме коммерческих, но с обязательным упоминанием автора материала." 16 | ] 17 | }, 18 | { 19 | "cell_type": "markdown", 20 | "metadata": {}, 21 | "source": [ 22 | "# Командный проект. Задача \"Закон джунглей\"\n", 23 | "### Задача из курса ШАД «Яндекс» по Python (с разрешения преподавателя Алексея Зобнина)\n", 24 | "" 25 | ] 26 | }, 27 | { 28 | "cell_type": "markdown", 29 | "metadata": {}, 30 | "source": [ 31 | "Напишите программу, моделирующую экологическую систему океана, в котором обитают хищники и жертвы. \n", 32 | "\n", 33 | "Океан представляется двумерным массивом ячеек. В ячейке может находиться либо хищник, либо жертва, либо препятствие. В каждый квант времени ячейки последовательно обрабатываются. Хищник может съесть соседнюю жертву или просто переместиться на соседнюю клетку, добыча также может переместиться на соседнюю клетку. Если в течение некоторого времени хищник ничего не съел, он погибает. Через определенные интервалы времени хищники и жертвы размножаются, если рядом есть свободная ячейка. При этом потомок занимает свободную ячейку. \n", 34 | "\n", 35 | "Текущее состояние экрана отображается на экране, желательно в виде графического интерфейса. Моделирование закачивается либо по истечении некоторого числа итераций, либо когда погибнут все хищники или жертвы. \n", 36 | "\n", 37 | "Проверьте на этой модели гипотезу о цикличности популяций хищников и жертв. " 38 | ] 39 | }, 40 | { 41 | "cell_type": "markdown", 42 | "metadata": {}, 43 | "source": [ 44 | "## Начало решения" 45 | ] 46 | }, 47 | { 48 | "cell_type": "code", 49 | "execution_count": 1, 50 | "metadata": { 51 | "collapsed": true 52 | }, 53 | "outputs": [], 54 | "source": [ 55 | "from __future__ import print_function\n", 56 | "from IPython.display import clear_output\n", 57 | "from time import sleep\n", 58 | "from random import choice" 59 | ] 60 | }, 61 | { 62 | "cell_type": "markdown", 63 | "metadata": {}, 64 | "source": [ 65 | "**Инициализация поля размерами SIZE_X (по горизонтали, т.е. число столбцов) на SIZE_Y (по вертикали, т.е число строк).\n", 66 | "На поле случайным образом бросаются NUM_PRED хищников ('X'), NUM_VIC жертв ('O') и NUM_OBST препятствий ('#').**" 67 | ] 68 | }, 69 | { 70 | "cell_type": "code", 71 | "execution_count": 2, 72 | "metadata": { 73 | "collapsed": true 74 | }, 75 | "outputs": [], 76 | "source": [ 77 | "SIZE_X, SIZE_Y = 10, 4\n", 78 | "NUM_PRED, NUM_VIC, NUM_OBST = 2, 4, 4\n", 79 | "\n", 80 | "def initialize_field():\n", 81 | " '''\n", 82 | " Returns a list of SIZE_X lists (each of length SIZE_y)\n", 83 | " with NUM_PRED 'X's (for predators), NUM_VIC 'O's (for victims)\n", 84 | " and NUM_OBST '#'s (for obstacles) in random places. Each remaining element\n", 85 | " contains a '*'.\n", 86 | " '''\n", 87 | " field = [['*'] * SIZE_X for y in range(SIZE_Y)]\n", 88 | " cell_idx = [(x, y) for x in xrange(SIZE_X)\n", 89 | " for y in xrange(SIZE_Y)]\n", 90 | " \n", 91 | " # add predators\n", 92 | " num_pred = NUM_PRED\n", 93 | " while(num_pred):\n", 94 | " col, row = choice(cell_idx)\n", 95 | " if field[row][col] == '*':\n", 96 | " field[row][col] = 'X'\n", 97 | " num_pred -= 1\n", 98 | " \n", 99 | " # add victims\n", 100 | " num_vic = NUM_VIC\n", 101 | " while(num_vic):\n", 102 | " col, row = choice(cell_idx)\n", 103 | " if field[row][col] == '*':\n", 104 | " field[row][col] = 'O'\n", 105 | " num_vic -= 1\n", 106 | " \n", 107 | " # add obstacles\n", 108 | " num_obst = NUM_OBST\n", 109 | " while(num_obst):\n", 110 | " col, row = choice(cell_idx)\n", 111 | " if field[row][col] == '*':\n", 112 | " field[row][col] = '#'\n", 113 | " num_obst -= 1\n", 114 | " \n", 115 | " return field" 116 | ] 117 | }, 118 | { 119 | "cell_type": "markdown", 120 | "metadata": {}, 121 | "source": [ 122 | "**Печать поля. Если clear_all влючен, весь предыдущий вывод затрется. В совокупности с функцией sleep из time можно печатать одно и то же поле в разные моменты времени, а не подряд несколько полей.**" 123 | ] 124 | }, 125 | { 126 | "cell_type": "code", 127 | "execution_count": 3, 128 | "metadata": { 129 | "collapsed": true 130 | }, 131 | "outputs": [], 132 | "source": [ 133 | "def print_field(field, clear_all=True):\n", 134 | " '''\n", 135 | " Prints the field (a list of lists). If the field is big, it sucks :)\n", 136 | " \n", 137 | " :param field - a list of lists\n", 138 | " :param clear_all - whether to clear previous output.\n", 139 | " '''\n", 140 | " if clear_all:\n", 141 | " clear_output()\n", 142 | " print('/' * (2 * SIZE_X + 5))\n", 143 | " for col in range(len(field)):\n", 144 | " print('// ', end='')\n", 145 | " for row in range(len(field[0])):\n", 146 | " print(field[col][row], end=' ')\n", 147 | " print('//')\n", 148 | " print('/' * (2 * SIZE_X + 5))" 149 | ] 150 | }, 151 | { 152 | "cell_type": "markdown", 153 | "metadata": {}, 154 | "source": [ 155 | "**Обработка одной клетки в один момент времени. Пока реализован только переход в соседнюю клетку. Если это хищник или жертва и рядом (по горизонтали или вертикали) есть свободные клетки, хищник (или жертва) переходит в одну из случайно выбранных свободных клеток.**" 156 | ] 157 | }, 158 | { 159 | "cell_type": "code", 160 | "execution_count": 4, 161 | "metadata": { 162 | "collapsed": true 163 | }, 164 | "outputs": [], 165 | "source": [ 166 | "def process_one_cell(field, (col, row)):\n", 167 | " '''\n", 168 | " If a cell (col, row) is occupied with 'X' or 'O'\n", 169 | " it modifies the field and returns a new one.\n", 170 | " \n", 171 | " :param field - a list of lists\n", 172 | " :param (col, row) - a tuple with 2 integer coordinates.\n", 173 | " col should be in [0, SIZE_X - 1],\n", 174 | " row should be in [0, SIZE_Y - 1]\n", 175 | " :return field, (new_col, new_row) - filed is a modified list of lists,\n", 176 | " (new_col, new_row) - are the coordinates of a new cell\n", 177 | " or the old obe if there was no movement\n", 178 | " '''\n", 179 | " if field[col][row] in ['X', 'O']:\n", 180 | " cur_animal = field[col][row]\n", 181 | " possible_moves = []\n", 182 | " for (new_col, new_row) in [(col, min(row + 1, SIZE_X - 1)),\n", 183 | " (col, max(row - 1, 0)),\n", 184 | " (max(col - 1, 0), row),\n", 185 | " (min(col + 1, SIZE_Y - 1), row)]:\n", 186 | " if field[new_col][new_row] == \"*\":\n", 187 | " possible_moves.append((new_col, new_row))\n", 188 | " if possible_moves:\n", 189 | " new_col, new_row = choice(possible_moves)\n", 190 | " field[new_col][new_row] = cur_animal\n", 191 | " field[col][row] = '*'\n", 192 | " return field, (new_col, new_row)\n", 193 | " return field, (col, row)" 194 | ] 195 | }, 196 | { 197 | "cell_type": "markdown", 198 | "metadata": {}, 199 | "source": [ 200 | "**Функция для запуска обработки всех клеток поля. Здесь учитывается, что если на прошлом шаге в некоторую клетку пришел хищник или жертва, то ее уже не надо обрабатывать.**" 201 | ] 202 | }, 203 | { 204 | "cell_type": "code", 205 | "execution_count": 5, 206 | "metadata": { 207 | "collapsed": true 208 | }, 209 | "outputs": [], 210 | "source": [ 211 | "def process_field(field, verbose=False):\n", 212 | " '''\n", 213 | " Applies process_one_cell to each cell with repsect to the fact \n", 214 | " that a cell should not be processed if it has already been a destination\n", 215 | " of a previous move.\n", 216 | " \n", 217 | " :param field - a list of lists\n", 218 | " :param verbose - whether to print the moves\n", 219 | " \n", 220 | " :return field - a modified list of lists\n", 221 | " '''\n", 222 | " processed_cells = []\n", 223 | " for col in range(SIZE_Y):\n", 224 | " for row in range(SIZE_X):\n", 225 | " if (col, row) not in processed_cells:\n", 226 | " field, (new_col, new_row) = process_one_cell(field, (col, row))\n", 227 | " if (new_col, new_row) != (col, row):\n", 228 | " if verbose:\n", 229 | " print(\"{} steps {}->{}\".format(field[new_col][new_row],\n", 230 | " (col, row), (new_col, new_row)))\n", 231 | " processed_cells.append((new_col, new_row))\n", 232 | " return field\n", 233 | " " 234 | ] 235 | }, 236 | { 237 | "cell_type": "markdown", 238 | "metadata": {}, 239 | "source": [ 240 | "**Проверка на игрушечном примере. Посмотрим, как переместились 2 хищника и 3 жертвы за один ход. Чтоб разобраться было проще, напечатаем координаты ходов.**" 241 | ] 242 | }, 243 | { 244 | "cell_type": "code", 245 | "execution_count": 6, 246 | "metadata": { 247 | "collapsed": false 248 | }, 249 | "outputs": [ 250 | { 251 | "name": "stdout", 252 | "output_type": "stream", 253 | "text": [ 254 | "/////////////////////////\n", 255 | "// * * # * * X O * * * //\n", 256 | "// * * * X # * * * # * //\n", 257 | "// * * * * * # O * * * //\n", 258 | "// * * * * * * * * O O //\n", 259 | "/////////////////////////\n", 260 | "X steps (0, 5)->(1, 5)\n", 261 | "O steps (0, 6)->(0, 7)\n", 262 | "X steps (1, 3)->(1, 2)\n", 263 | "O steps (2, 6)->(2, 7)\n", 264 | "O steps (3, 8)->(2, 8)\n", 265 | "O steps (3, 9)->(3, 8)\n", 266 | "/////////////////////////\n", 267 | "// * * # * * * * O * * //\n", 268 | "// * * X * # X * * # * //\n", 269 | "// * * * * * # * O O * //\n", 270 | "// * * * * * * * * O * //\n", 271 | "/////////////////////////\n" 272 | ] 273 | } 274 | ], 275 | "source": [ 276 | "f = initialize_field()\n", 277 | "print_field(f)\n", 278 | "f = process_field(f, verbose=True)\n", 279 | "sleep(1)\n", 280 | "print_field(f, clear_all=False)" 281 | ] 282 | } 283 | ], 284 | "metadata": { 285 | "anaconda-cloud": {}, 286 | "kernelspec": { 287 | "display_name": "Python [default]", 288 | "language": "python", 289 | "name": "python2" 290 | }, 291 | "language_info": { 292 | "codemirror_mode": { 293 | "name": "ipython", 294 | "version": 2 295 | }, 296 | "file_extension": ".py", 297 | "mimetype": "text/x-python", 298 | "name": "python", 299 | "nbconvert_exporter": "python", 300 | "pygments_lexer": "ipython2", 301 | "version": "2.7.12" 302 | } 303 | }, 304 | "nbformat": 4, 305 | "nbformat_minor": 0 306 | } 307 | -------------------------------------------------------------------------------- /src/victims_predators_base.py: -------------------------------------------------------------------------------- 1 | 2 | # coding: utf-8 3 | 4 | # # Командный проект. Задача "Закон джунглей" 5 | # ### Задача из курса ШАД «Яндекс» по Python (с разрешения преподавателя Алексея Зобнина) 6 | 7 | # Напишите программу, моделирующую экологическую систему океана, в котором обитают хищники и жертвы. 8 | # 9 | # Океан представляется двуxмерным массивом ячеек. В ячейке может находиться либо хищник, либо жертва, либо препятствие. В каждый квант времени ячейки последовательно обрабатываются. Хищник может съесть соседнюю жертву или просто переместиться на соседнюю клетку, добыча также может переместиться на соседнюю клетку. Если в течение некоторого времени хищник ничего не съел, он погибает. Через определенные интервалы времени хищники и жертвы размножаются, если рядом есть свободная ячейка. При этом потомок занимает свободную ячейку. 10 | # 11 | # Текущее состояние экрана отображается на экране, желательно в виде графического интерфейса. Моделирование закачивается либо по истечении некоторого числа итераций, либо когда погибнут все хищники или жертвы. 12 | # 13 | # Проверьте на этой модели гипотезу о цикличности популяций хищников и жертв. 14 | 15 | # ## Начало решения 16 | 17 | from __future__ import print_function 18 | import os 19 | from time import sleep 20 | from random import choice 21 | 22 | 23 | # Инициализация поля размерами SIZE_X (по горизонтали, т.е. число столбцов) на SIZE_Y (по вертикали, т.е число строк). 24 | # На поле случайным образом бросаются NUM_PRED хищников ('X'), NUM_VIC жертв ('O') и NUM_OBST препятствий ('#'). 25 | 26 | SIZE_X, SIZE_Y = 10, 4 27 | NUM_PRED, NUM_VIC, NUM_OBST = 2, 4, 4 28 | 29 | def initialize_field(): 30 | ''' 31 | Returns a list of SIZE_X lists (each of length SIZE_y) 32 | with NUM_PRED 'X's (for predators), NUM_VIC 'O's (for victims) 33 | and NUM_OBST '#'s (for obstacles) in random places. Each remaining element 34 | contains a '*'. 35 | ''' 36 | field = [['*'] * SIZE_X for y in range(SIZE_Y)] 37 | cell_idx = [(x, y) for x in xrange(SIZE_X) 38 | for y in xrange(SIZE_Y)] 39 | 40 | # add predators 41 | num_pred = NUM_PRED 42 | while(num_pred): 43 | col, row = choice(cell_idx) 44 | if field[row][col] == '*': 45 | field[row][col] = 'X' 46 | num_pred -= 1 47 | 48 | # add victims 49 | num_vic = NUM_VIC 50 | while(num_vic): 51 | col, row = choice(cell_idx) 52 | if field[row][col] == '*': 53 | field[row][col] = 'O' 54 | num_vic -= 1 55 | 56 | # add obstacles 57 | num_obst = NUM_OBST 58 | while(num_obst): 59 | col, row = choice(cell_idx) 60 | if field[row][col] == '*': 61 | field[row][col] = '#' 62 | num_obst -= 1 63 | 64 | return field 65 | 66 | 67 | # Печать поля. Если clear_all влючен, весь предыдущий вывод затрется. В совокупности с функцией sleep из time можно печатать одно и то же поле в разные моменты времени, а не подряд несколько полей. 68 | 69 | 70 | def clear_output(): 71 | os.system('cls' if os.name=='nt' else 'clear') 72 | 73 | def print_field(field, clear_all=True): 74 | ''' 75 | Prints the field (a list of lists). If the field is big, it sucks :) 76 | 77 | :param field - a list of lists 78 | :param clear_all - whether to clear previous output. 79 | ''' 80 | if clear_all: 81 | clear_output() 82 | print('/' * (2 * SIZE_X + 5)) 83 | for col in range(len(field)): 84 | print('// ', end='') 85 | for row in range(len(field[0])): 86 | print(field[col][row], end=' ') 87 | print('//') 88 | print('/' * (2 * SIZE_X + 5)) 89 | 90 | 91 | # Обработка одной клетки в один момент времени. Пока реализован только переход в соседнюю клетку. Если это хищник или жертва и рядом (по горизонтали или вертикали) есть свободные клетки, хищник (или жертва) переходит в одну из случайно выбранных свободных клеток. 92 | 93 | def process_one_cell(field, (col, row)): 94 | ''' 95 | If a cell (col, row) is occupied with 'X' or 'O' 96 | it modifies the field and returns a new one. 97 | 98 | :param field - a list of lists 99 | :param (col, row) - a tuple with 2 integer coordinates. 100 | col should be in [0, SIZE_X - 1], 101 | row should be in [0, SIZE_Y - 1] 102 | :return field, (new_col, new_row) - filed is a modified list of lists, 103 | (new_col, new_row) - are the coordinates of a new cell 104 | or the old obe if there was no movement 105 | ''' 106 | if field[col][row] in ['X', 'O']: 107 | cur_animal = field[col][row] 108 | possible_moves = [] 109 | for (new_col, new_row) in [(col, min(row + 1, SIZE_X - 1)), 110 | (col, max(row - 1, 0)), 111 | (max(col - 1, 0), row), 112 | (min(col + 1, SIZE_Y - 1), row)]: 113 | if field[new_col][new_row] == "*": 114 | possible_moves.append((new_col, new_row)) 115 | if possible_moves: 116 | new_col, new_row = choice(possible_moves) 117 | field[new_col][new_row] = cur_animal 118 | field[col][row] = '*' 119 | return field, (new_col, new_row) 120 | return field, (col, row) 121 | 122 | 123 | # Функция для запуска обработки всех клеток поля. Здесь учитывается, что если на прошлом шаге в некоторую клетку пришел хищник или жертва, то ее уже не надо обрабатывать. 124 | 125 | def process_field(field, verbose=False): 126 | ''' 127 | Applies process_one_cell to each cell with repsect to the fact 128 | that a cell should not be processed if it has already been a destination 129 | of a previous move. 130 | 131 | :param field - a list of lists 132 | :param verbose - whether to print the moves 133 | 134 | :return field - a modified list of lists 135 | ''' 136 | processed_cells = [] 137 | for col in range(SIZE_Y): 138 | for row in range(SIZE_X): 139 | if (col, row) not in processed_cells: 140 | field, (new_col, new_row) = process_one_cell(field, (col, row)) 141 | if (new_col, new_row) != (col, row): 142 | if verbose: 143 | print("{} steps {}->{}".format(field[new_col][new_row], 144 | (col, row), (new_col, new_row))) 145 | processed_cells.append((new_col, new_row)) 146 | return field 147 | 148 | 149 | 150 | # Проверка на игрушечном примере. Посмотрим, как переместились 2 хищника и 3 жертвы за один ход. Чтоб разобраться было проще, напечатаем координаты ходов. 151 | 152 | 153 | f = initialize_field() 154 | print_field(f) 155 | f = process_field(f, verbose=True) 156 | sleep(1) 157 | print_field(f, clear_all=False) 158 | 159 | --------------------------------------------------------------------------------