timeit

Програмиране с Python

Курс във Факултета по Математика и Информатика към СУ

Морски шах

  1. За малкото време, което имахме на последната ни сбирка стигнахме до едно недовършено положение с нашия морски шах, практикувайки TDD. Това е една страхотна възможност за всеки един от вас, който не е опитвал TDD до сега. Кодът, който написахме по време на лекцията можете да намерите тук: https://gist.github.com/vladimiroff/633dec5791d59d3a4f5b

    Това определено не е завършено решение и мога да ви дам няколко идеи за подобрение. Опитайте се да ги решите, спазвайки описаните стъпки:

    • На места виждаме _Board__grid__, което веднага ни казва, че или този атрибут не трябва да се използва така или не трябва да е private (а примерно protected). Дори в тестове, освен ако не сме в особено екзотична ситуация, а тази не е такава. Оставям на вас да прецените дали да не използвате private атрибут, в тестовете да "симулирате" ходовете или да си дефинирате метод за "import" на игра.

    • Имаме дефинирани константи за 'X' и 'O', но нямаме такава за празно поле. Също така не ги използваме в тестовете.

    • Въпреки, че import реда във файла с тестове минава автоматизираната PEP8 проверка, определено не изглежда добре.

    • Опитайте се да намерите неизтествани от тези тестове случаи.

    • Имаме две дефинирани изключения. С повече желание, можем да ги направим повече и малко по-конкретни. Оставям на вас да решите дали има нужда от това (аргументации и за двете решения са добре дошли).

    Идеи за нови функционалности:

    • Save/Load (или Export/Import) на игра. Нуждата от подобно нещо вече беше засегната в първия ни "кусур", но подобна функционалност е често срещана и може да се използва не само за улеснение по време на тестване.

    • Дъската ни в момента е 3x3. Не би следвало да е особено сложно да се направи NxN, където N е атрибут на инициализатора на Board. От тук и нуждата да се обърне повече внимание на неща, които предпочетохме да напишем директно с обяснението "дъската ни е 3x3, а не 100х100" по време на сбирката.

    • Визуализация в команден ред на дъската. Споменахме, че това ще е добра идея да бъде имплементирано, но така и не стигнахме до него. Един Board.__str__ би следвало да е напълно достатъчен.

    • Така наречения Main loop за да може да се играе нашата игра и от обикновени хора... които са свикнали да работят в команден ред.

    Най-вероятно можете да се сетите за още подобрения, които ги няма в тези два списъка. Публикувайте линкове към вашите имплементирации на подобрения, а ние ще даваме точки :)

  2. Ако създам списъка за полето така

    [[EMPTY] * size] * size
    

    и после добавя елемент на позиция А1, той се появява и на А2, и А3. По какъв начин да създам списъка, за да не се отразява и на останалите?

    Edit: Стана с list comprehension, но е доста по-дълго.

    [[EMPTY] * size for _ in range(size)]
    

    Добра идея ли е да хвърляме изключение при края на играта вместо да връщаме някоя от константите?

  3. Добра идея ли е да хвърляме изключение при края на играта вместо да връщаме някоя от константите?

    Не. Краят на играта не е грешка :)

    Аз мога да стартирам твоята игра с python tic_tac_toe.py.

    Иначе, гледайки твоето решение width и height са излишни при наличието на __size.

  4. По този начин [[EMPTY] * size] * size ти създаваш size на брой референции към един и същ списък и затова при промяна на A1 се променят и останалите клетки в тази колона.

    В main функцията на решението си можеш да се опиташ да хванеш и обработиш всички изключения, които могат да се случат, така че да не гърми цялата игра, ако се въведе нещо грешно (аз не сложих кавички на координатите и щеше да ми е полезно да ми изведе някакво съобщение за невалиден вход и да ми даде шанс да се поправя вместо да гръмне :smile: )

  5. @Виктория Ами по този начин защо не се получават едни и същи референции към EMPTY?

    [EMPTY] * size
    

    Пооправих main-a, но координатите са правилни точно, когато няма кавички. Ако се сложат, низа, който получава _convert_to_coords е нещо като '\"A1\"' и се чупи.

  6. Всъщност са едни и същи. Но са просто референции към str обекти, които са immutable:

    >>> row = [EMPTY] * size
    >>> row[0] is row[1] is row[2]
    <<< True
    

    edit: Харесва ми, че си имплементирал всички нови функционалности и си адресирал почти всички (без една) забележки за подобрение. Награда: 3 точки :)

Трябва да сте влезли в системата, за да може да отговаряте на теми.