Курсовая работа: Программа Спички Берсгона

Внимание! Если размещение файла нарушает Ваши авторские права, то обязательно сообщите нам

ФЕДЕРАЛЬНОЕ АГЕНТСТВО ЖЕЛЕЗНОДОРОЖНОГО ТРАНСПОРТА

ФЕДЕРАЛЬНОЕ ГОСУДАРСТВЕННОЕ БЮДЖЕТНОЕ ОБРАЗОВАТЕЛЬНОЕ

УЧРЕЖДЕНИЕ ВЫСШЕГО ПРОФЕССИОНАЛЬНОГО ОБРАЗОВАНИЯ

«ОМСКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ

ПУТЕЙ СООБЩЕНИЯ» (ОМГУПС (ОМИИТ))

Программа «СПИЧКИ БЕРСГОНА»

Пояснительная записка к курсовой работе

ИНМВ.400000.000 ПЗ

Студент гр. 25м

________ Ильин А. В.

21.04.2014

Руководитель - доцент кафедры АиСУ

________ Александров А. В.

«__»________2014 г.

Омск 2016

Реферат

Пояснительная записка к курсовой работе содержит 12 страниц, 3 рисунка, 4 использованных источника, приложение А.

Объектом исследования является игра «Спички Бергсона».

Цель курсовой работы - систематизация, углубление и активное применение знаний по системному программированию, закрепление знаний, полученных в лекционном курсе, а также на практических и лабораторных занятиях.

Игра «Спички Бергсона» разработана с использованием компилятора GCC. Исходный текст программы написан на языке «Си».

В процессе разработки игры была изучена лексика языка «Си».

Пояснительная записка выполнена в текстовом редакторе Microsoft Word 2016.

Задание

В ходе выполнения курсовой работы нужно реализовать игру. Все игры являются пошаговыми, с интерфейсом командной строки. Компьютер выводит в текстовом виде информацию о состоянии игры и ходе пользователя. Пользователь делает свой ход, вводя с клавиатуры нужные данные.

На столе лежит кучка спичек. При своем ходе игрок может взять спичек не меньше одной и не более чем вдвое больше, чем взял предыдущий игрок. Выигрывает тот, кто берет последнюю спичку.

Введение

Курсовая работа написана на языке «Cи», компилируемом, статически типизированном языке программирования общего назначения. В ней реализована задача игры «Спички Бергсона». «Cи» - стандартизированный процедурный язык программирования.

Язык «Cи» был разработан в начале 1970-х годов сотрудниками Bell Labs Кеном Томпсоном и Денисом Ритчи как наследник языка «B».

«Cи» был создан для использования в операционной системе UNIX, в том числе и для написания ядра системы. С тех пор он был портирован на многие другие операционные системы и стал одним из самых широко используемых языков программирования.

В 1978 году была опубликована книга «Язык программирования Cи» Ритчи и Кернигана; описанный в ней язык стал неформальным стандартом языка, известным как K&R «Cи».

Первый официальный стандарт языка был создан в 1989 году ANSI X3.159-1989 и в следующем году с незначительными изменениями принят как ISO/IEC 9899:1990; он известен как ANSI C. Следующими стандартами стали ISO 9899:1999 (C99) и ISO/IEC 9899:2011 (C11).

«Cи» ценят за его эффективность; он является самым популярным языком для создания системного программного обеспечения. Его также часто используют для создания прикладных программ.

Особенности языка:

- минимальное количество ключевых слов;

- большинство возможностей языка вынесено в библиотеки; использование препроцессора для определения макросов, включения исходных кодов других файлов и условной компиляции;

- статическая слабая типизация: у всех данных есть фиксированные типы, но неявные преобразования разрешены;

- разрешено определение пользовательских типов и составных типов;

- предоставляется низкоуровневый доступ к памяти (через преобразование машинных адресов в типизированные указатели);

- процедуры являются частным случаем функции, возвращающей специальный тип «void»;

- файлы можно компилировать отдельно и линковать друг с другом, контролируя видимость функций и данных ключевыми словами «static» и «extern».

Написанная игра является пошаговой, игрок вводит данные с клавиатуры, а компьютер выводит на экран результаты его хода.

Основная часть

В коде программы используется специальный тип данных PlayerT, для разграничения ходов игрока и компьютера, и ряд функций, такие как:

void winnerIs(int nMatches, playerT whoseTurn) - объявляет выигрыш игрока или компьютера.

int userMove(int nMatches) - обрабатывает ходы игрока.

bool isthisLegal(int nTaken, int nMatches) - проверяет ходы на соответсвие правилам игры, запрещает игроку взять больше спичек чем требуется.

int aiMove (int nMatches) - обрабатывает ходы компьютера.

int goodMove(int nMatches) - вместе с функцией bool isbadPosition(int nMatches) ищет наиболее выгодный ход для компьютера. Компьютер старается взять столько спичек, сколько потребуется для того, чтобы поставить пользователя в невыгодное положение на следующем ходу.

При запуске игры, пользователь видит приветствие, объясняющие ему правила игры, и предложение выбрать количество спичек, которые будут разыгрываться. Принимаются любые значения, в случае если игрок введет ноль программа автоматически завершит свою работу.

Рисунок 1 - Начало игры

После того, как пользователь выбрал количество спичек, начинается игра. Игрок всегда ходит первым.

Рисунок 2 - Игровое поле

Игра будет продолжаться до тех пор, пока кто-то не возьмет последнюю спичку.

Рисунок 3 - Поражение

Текущие правила поведения компьютерного соперника делают победу игрока маловероятной, хотя все же возможной.

Заключение

программирование игра спички бергсон

В ходе выполнения задания на курсовую работу, были углублены знания по многим аспектам языка «Си».

Основная цель работы была выполнена, т.е. была написана пошаговая логическая игра «Спички Бергсона» с псевдографическим интерфейсом.

В результате выполнения курсовой работы разработана программа на языке «Си», в текстовом редакторе «Sublime Text», реализующая процесс, описанный в постановке задачи. В ходе написания игры был более подробно изучен язык.

В программе реализована возможность игры с компьютером, ходы компьютера исходят из уже имеющихся данных и анализа количества оставшихся спичек.

Считаю, что поставленная задача решена в полном объеме.

В приложении А содержится код программы, содержащий все пояснительные комментарии.

Библиографический список

1. Введение в программирование: Методические указания к лабораторным работам / Е. А. Альтман, А. В. Александров, Н. Г. Ананьева, Н. Е. Актаев; Омский гос. ун-т путей сообщения. Омск, 2011. 31 с.

2. Керниган. Б., Ритчи Д., Язык программирования «Си». 2-е издание , 2012.-304 с.

3. СТП ОмГУПС-1.2-2005

4. СТП ОмГУПС-1.2-02

5. Гpиффитс, Артур. GCC: Настольная книга пользователей, программистов и системных администраторов.: Пер. с анrл./Артур Гриффитс. К.: ООО «ТИД «ДС», 2004. 624 с.

Приложение А

(обязательное)

Листинг программы

#include <stdio.h>

#include <stdbool.h>

#define NoGoodMove -1 //константа для ситуации «плохого хода»

int iniMatches=0; //начальное колличество спичек, не задано

int MaxTake =1; //начальное кол-во спичек, которые можно взять

typedef enum { Human, Computer } playerT; //различаем ходы человека и компьютера

static void winnerIs(int nMatches, playerT whoseTurn); //прототипы функции

static int userMove(int nMatches);

static bool isthisLegal(int nTaken, int nMatches);

static int aiMove(int nMatches);

static int goodMove(int nMatches);

static bool isbadPosition(int nMatches);

int main()

{

int nMatches, nTaken;

playerT whoseTurn;

printf("Привет, добро пожаловать в игру Спички Бергсона.\n");

printf("В этой игре каждый игрок поочередно берет спички из общей кучи\n");

printf("Не меньше одной и не больше, чем взял другой игрок");

printf("Тот, кто возьмет последнюю - побеждает");

printf("А сейчас выберете начальное колличество спичек\n" );

scanf("%i",&iniMatches);

nMatches = iniMatches;

whoseTurn = Human;

while (nMatches > 1) {

printf("Сейчас у нас %d спичек.\n", nMatches);

switch (whoseTurn) {

case Human:

nTaken = userMove(nMatches);

MaxTake=2*nTaken;

whoseTurn = Computer;

break;

case Computer:

nTaken = aiMove(nMatches);

printf("Я возьму %d.\n", nTaken);

MaxTake=2*nTaken;

whoseTurn = Human;

break;

}

nMatches -= nTaken;

}

winnerIs(nMatches, whoseTurn);

}

static void winnerIs(int nMatches, playerT whoseTurn)

{

if (nMatches == 0) {

switch (whoseTurn) {

printf(«Спичек не осталось. Победа»)

}

} else {

printf("Осталась лишь одна спичка.\n");

switch (whoseTurn) {

case Human: printf("Я проиграл.\n"); break;

case Computer: printf("Я победил.\n"); break;

}

}

}

static int userMove(int nMatches)

{

int nTaken, limit;

while (true) {

printf("Сколько спичек надо взять?");

scanf("%i",&nTaken);

if (isthisLegal(nTaken, nMatches)) break;

limit = (nMatches < MaxTake) ? nMatches : MaxTake;

printf("Это неверный ход! Возьмите");

printf(" между 1 и %d спичками\n", limit);

printf("Осталось %d спичек.\n", nMatches);

}

return (nTaken);

}

Листинг А1, лист 1

static bool isthisLegal(int nTaken, int nMatches)

{

return (nTaken > 0 && nTaken <= MaxTake && nTaken <= nMatches);

}

static int aiMove(int nMatches)

{

int nTaken;

nTaken = goodMove(nMatches);

if (nTaken == NoGoodMove) nTaken = 1;

return (nTaken);

}

static int goodMove(int nMatches)

{

int nTaken;

for (nTaken = 1; nTaken <= MaxTake; nTaken++) {

if (isbadPosition(nMatches - nTaken)) return (nTaken);

}

return (NoGoodMove);

}

static bool isbadPosition(int nMatches)

{

if (((nMatches%2==1)&&!(nMatches<=3))||(nMatches<=0)) return (true); //смысл в том, чтобы поставить игрока в неудобную позицию, хотя я уверен что алгоритм не идеален

return (goodMove(nMatches) == NoGoodMove);

}