Студопедия

Главная страница Случайная страница

Разделы сайта

АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника






Программный код. //Программа: Игра в 15






 

//Имя файла: sliding.с

//Программа: Игра в " 15"

//Авторы: Scott Lewis, Daniel Pack,

//Дата создания: Начата 27 апреля 2004

//окончена 7 Мая 2004

// Описание: Эта программа реализует игру в " 15". Цель игры

// заключается в том, чтобы выстроить фишки по по ряду номеров. Вы

// можете только перемещать на пустое место любую соседнюю фишку.

// Программа постоянно находится в памяти системы по адресу

// $2000. Программа отображает исходное состояние фишек, затем

// показывает состояние к которому необходимо прийти в

// результате. Программа размещает все фишки в случайном

// порядке, и затем позволяет пользователю начать игру

// Конфигурация системы

// Программа: 0x2000

// Данные: 0x3500

// Стек: 0x4000

//

// PDLC0: /WR PP0 Data 0 PS0: Не используется

// PDLC1: /RD PP1 Data 1 PS1: Не используется

// PDLC2: /CE PP2 Data 2 PS2: Кнопка " Влево"

// PDLC3: C/D PP3 Data 3 PS3: Кнопка " Выбор"

// PDLC4: /Reset PP4 Data 4 PS4: Кнопка " Вниз"

// PDLC5: NC PP5 Data 5 PS5: Кнопка " Вправо"

// PDLC6: NC PP6 Data 6 PS6: Кнопка " Вверх"

// PDLC1: NC PP7 Data 7 PS7: Не используется

//

// Выводы ЖКД

// GND - 2 1 - GND

// -14V - 3 4 - +5V

// /WR - 5 6 - /RD

// /CE - 7 8 - C/D

// NC - 9 10 - /Reset

// DO - 11 12 - D1

// D2 - 13 14 - D3

// D4 - 15 16 - D5

// D6 - 17 18 - D7

// GND - 19 20 - NC

//******************************************************

 

#include < 912b32.h> // описание портов - header file

// приведен в приложении

//********************************************************************

// Постоянные

//********************************************************************

#define ARRAY_MAX 15

#define ZERO 0x00

#define L_BUTTON 0x04 // сигналы кнопок

#define R_BUTTON 0x20

#define U_BUTTON 0x40

#define D_BUTTON 0x10

#define S BUTTON 0x08

 

#define LEFT 1 // выбор направления

#define RIGHT 2

#define UP 3

#define DOWN 4

#define SELECT 5

 

#define SIZE 4 // Размер строки/колонки

 

//********************************************************************

// Используемые функции

//********************************************************************

int check_win(int array[ARRAY_MAX+1]);

void convert_multi_single(int A[SIZE][SIZE], int В[SIZE][SIZE]);

void convert_single_multi(int A[ARRAY_MAX+1], int В[SIZE][SIZE]);

void display_board(int A[SIZE][SIZE], int row, int col, int direction);

void display_board2(int board_array[ARRAY_MAX+1]);

void display_error(int n);

void display_intro(void);

void display_win(void);

void get_move(int *direction, int *row, int *col, int *select);

void randomize_board(int board_array[]);

void swap(int row, int col, int new_row, int new_col, int array[SIZE][SIZE]);

void swap2(int from, int to, int array[ARRAY_MAX+1]);

void try_move(int move, int row, int col, int array[SIZE][SIZE]);

unsigned char mode(unsigned char num, int modulus);

void LCD_output(char s[]);

void int2char(int i);

void pause(void);

void delay(int usec);

void enable(void);

void initialize_LCD(void);

void command(unsigned char n);

void data(unsigned char n);

void write(void);

void read(void);

void status_wait(void);

void LCD_char(unsigned char n);

void Clearscreen(void);

void newline(void);

void Reset_cursor(void);

 

//*****************************************************************

//Переменные

//*****************************************************************

#pragma abs_address 0x3600

static int win_array[ARRAY_MAX+1]

= {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0};

#pragma end_abs_address

 

#pragma abs_address 0x3500

int board_array_single [ARRAY_MAX+1];

int board_array_multi[SIZE][SIZE];

int win; //использовать как булевы переменные

int direction; //направление движения

int row; //выделить ряд

int col; //выделить колонку

int select; //если кнопка нажата

int i; //текущая переменная

#pragma end_abs_address

 

//*****************************************************************

// Основная программа

//*****************************************************************

void main() {

win = 0; //инициализировать все переменные

direction = 0;

row = 1;

col = 1;

select = 0;

i = 0;

DDRDLC = 0x1F; //конфигурировать порт DDRDLC как выходной

DDRP = 0xFF; // конфигурировать линии порта P как выходные

DDRS = 0x00; // конфигурировать линии порта S как входные

TSCR = 0x80; //включить таймер

initialize_LCD(); //инициализировать ЖКД

Clearscreen();

Reset_cursor();

display_intro();

for (i=0; i < ARRAY_MAX+1; i++) board_array_single[i] = win_array[i];

convert_single_multi(board_array_single, board_array_multi);

display_board(board_array_multi, row, col, direction);

pause(); // ожидание, пока пользователь не нажмет кнопку X

LCD_output(" Now the board is"); // вывод сообщения

LCD_output(" randomized. You ");

LCD_output(" may begin by ");

LCD_output(" choosing a piece");

LCD_output(" to move, and its");

LCD_output(" direction. ");

newline();

pause();

randomize_board(board_array_single); // Случайный выбор исходного

// положения фишек

convert_single_multi(board_array_single, board_array_multi);

display_board(board_array_multi, row, col, direction);

while(win == 0){ //цикл повторяется до успешного окончания игры

while (select == 0) {

//если была нажата кнопка x, то задается направ-

// ление движения ряд и колонка выделенной фишки

get_move(& direction, & row, & col, & select);

Reset_cursor(); // установить курсор в верхнее положение

if (select == 0)

display_board(board_array_multi, row, col, direction);

}

//проверить корректность движения, повторить его, если

// оно некорректно, или вывести сообщение об ошибке

try_move(direction, row-1, col-1, board_array_multi);

select = 0;

convert_multi_single(board_array_multi, board_array_single);

win = check_win(board_array_single);

Clearscreen();

// показать текущее состояние игры

display_board(board_array_multi, row, col, direction);

}

display_win(); // вывести сообщение об успешном окончании игры

}

 

//*****************************************************************

// display_intro: DISPLAY INTRO MESSAGE

//*****************************************************************

void display_intro {

newline();

LCD_output(" WELCOME ");

LCD_output(" TO ");

LCD_output(" SLIDING PUZZLE ");

new_line();

pause();

LCD_output(" The object of ");

LCD_output(" this game is to ");

LCD_output(" move each #'ed ");

LCD_output(" puzzle piece so ");

LCD_output(" that you end up ");

LCD_output(" in the order ");

LCD_output(" seen below. The ");

LCD_output(" star shows the ");

LCD_output(" current piece ");

LCD_output(" selected. You ");

LCD_output(" can choose a ");

LCD_output(" different piece ");

LCD_output(" by using the ");

LCD_output(" arrow buttons ");

newline();

pause();

LCD_output(" and select the ");

LCD_output(" piece you want ");

LCD_output(" to move by ");

LCD_output(" pressing the X ");

// кнопка " Выбор"

LCD_output(" button. Choose ");

LCD_output(" the direction to ");

LCD_output(" move that piece ");

LCD_output(" with the arrows. ");

new_line();

LCD_output(" WINDING ");

LCD_output(" CONFIGURATION: ");

newline();

}

 

//*****************************************************************

// display_win: ВЫВОД СООБЩЕНИЯ О ПОБЕДЕ

//*****************************************************************

void display_win() {

LCD_output(" YOU WIN!!! ");

LCD_output(" CONGRATULATIONS ");

}

 

//********************************************************************

// get_move: ДВИЖЕНИЕ ФИШКИ: задается позиция фишки, выбранной игро-

// ком и направление ее движения

//********************************************************************

void get_move(int* direction, int *row, int *col, int* select) {

int n = 0;

int button = 0;

unsigned char temp = ZERO;

newline();

LCD_output(" Choose move or ");

LCD_output(" select piece: ");

while (button == 0) {

// цикл выполняется, пока нажата кнопка

temp = PORTS;

temp = temp & 0x7С

switch (temp) //какая кнопка нажата?

{

case L_BUTTON:

button = LEFT;

break;

case R_BUTTON:

button = RIGHT;

break;

case U_BUTTON:

button = UP;

break;

case D_BUTTON:

button = DOWN;

break;

case S_BUTTON:

button = SELECT;

break;

} // конец цикла switch

}//конец цикла while

n = 0;

switch (button) //реакция на нажатие кнопки

{

case UP:

if (*row > 1) *row -= 1;

else display_error(UP);

break;

case DOWN:

if (*row < SIZE) *row += 1;

else display_error(DOWN);

break;

case LEFT:

if (*col > 1) *col -= 1;

else display_error(LEFT);

break;

case RIGHT:

if (*col < SIZE) *col += 1

else display_error(RIGHT);

break;

case SELECT:

*select = 1;

LCD_output(" Pick a direction");

*direction = 0;

while (*direction == 0) {

temp = PORTS;

temp = temp & 0x7C;

switch (temp) {

case L_BUTTON:

*direction = LEFT;

break;

case R_BUTTON:

*direction = RIGHT;

break;

case U_BUTTON:

*direction = UP;

break;

case D_BUTTON:

*direction = DOWN;

break;

}

}

break;

}

}

 

//********************************************************************

// randomize_board: ВЫБОР СЛУЧАЙНОГО ИСХОДНОГО СОСТОЯНИЯ ФИШЕК

//********************************************************************

void randomize_board(int board_array[]) {

int temp = 0;

int i;

unsigned char temp2 = 0x00;

for (i=0; i< ARRAY_MAX+1; i++) {

temp2 = TCNTL;

temp = mod(temp2, 15); //случайное значение using the TCNT counter

swap2(i, temp, board_array);

}

}

 

//********************************************************************

// MOD: МАТЕМАТИЧЕСКАЯ ФУНКЦИЯ

//********************************************************************

unsigned char mod(unsigned char num, int modulus) {

while ((num - modulus) > 0) num = num - modulus;

return num;

}

 

//********************************************************************

// display_board2: Выводит табло, как одну колонку значений

//********************************************************************

void display_board2(int board_array[ARRAY_MAX+1]) {

int = 0;

int n;

for (i=0; i< ARRAY_MAX+1; i++) {

n = board_array[i];

int2char(n);

}

LCD_output(" \n");

}

 

//********************************************************************

// display_board: Выводит табло как массив 4& #215; 4

//********************************************************************

void display_board(int A[SIZE][SIZE], int row, int col, int direction) {

#pragma abs_address 0x0800

int i;

int j;

int num;

#pragma end_abs_address

newline();

LCD_output(" | Column ");

LCD_output(" | 1 2 3 4 ");

LCD_output(" -------------------");

for (i=0; i < SIZE; i++) {

j=0;

switch(i) {

case 0:

LCD_output(" R 1 |");

break;

case 1:

LCD_output(" o 2 |");

break;

case 2:

LCD_output(" w 3 |");

break;

case 3:

LCD_output(" 4 |");

break;

}

for (j=0; j < SIZE; j++) {

num = A[i][j];

if (num == 0) LCD_output(" ");

else int2char(num);

if ((i+1 == row) & & (j+1) == col))

LCD_output(" *");

else LCD_output(" ");

}

}

newline();

LCD_output(" You are at (R, C)");

LCD_output(" (");

int2char(row);

LCD_output(", ");

int2char(col);

LCD_output(") =");

int2char(A[row-1];

LCD_output(" ");

newline();

}

 

//********************************************************************

// INT2CHAR: задается как integer и выводится на ЖКД в виде

// двух символов

//********************************************************************

void int2char(int i) {

if (i > 9) {

LCD_output(" I");

i -= 10;

} else {

LCD_output('; ");

}

switch(i) {

case 0:

LCD_output(" 0");

break;

case 1:

LCD_output(" 1");

break;

case 2:

LCD_output(" 2");

break;

case 3:

LCD_output(" 3");

break;

case 4:

LCD_output(" 4");

break;

case 5:

LCD_output(" 5");

break;

case 6:

LCD_output(" 6");

break;

case 7:

LCD_output(" 7");

break;

case 8:

LCD_output(" 8");

break;

case 9:

LCD_output(" 9");

break;

}

}

 

//********************************************************************

//Check_Win: Эта функция проверяет соответствие текущего положения ситуации

// победы при победе win - 1, в остальных случаях - 0

//********************************************************************

int check_win(int array[ARRAY_MAX+1]) {

int i;

int win = 1;

for (i=0; i< ARRAY_MAX+1; i++) {

if (array[i]! = win_array[i]) win = 0;

}

return win;

}

 

//********************************************************************

//Convert_multi_single: Эта функция преобразует двухмерный массив

//в одномерный

//********************************************************************

int convert_multi_single(int A[SIZE][SIZE], int В[ARRAY_MAX+1]) {

int n = 0;

int i = 0;

int j = 0;

for (i=0; i< SIZE; i++) {

for (j=0; j< SIZE; j++) {

B[n] = A[i][j];

n++;

}

}

}

 

//****************************************************************

//Convert_single_multi: Эта функция преобразует одномерный массив

//в двухмерный

//****************************************************************

void convert_single_multitint A[ARRAY_MAX+1], int В[SIZE][SIZE]) {

B[0][0] = A[0];

B[0][1] = A[1];

B[0][2] = A[2];

B[0][3] = A[3];

B[1][0] = A[4];

B[1][1] = A[5];

B[1][2] = A[6];

B[1][3] = A[7];

B[2][0] = A[8];

B[2][1] = A[9];

B[2][2] = A[10];

B[2][3] = A[11];

B[3][0] = A[13];

B[3][2] = A[14];

B[3][3] = A[15];

}

 

//********************************************************************

// Try_move: Эта функция позволяет игроку определить некорректность

// своего хода. Если он корректен, то движение выполняется,

// если же некорректен, то выводится соответствующее сообщение

//********************************************************************

void try_move(int move, int row, int col, int array[SIZE][SIZE]) {

switch(move) {

case UP:

if ((row-1 > =0) & & (array[row-1][col] == 0))

swap(row, col, row-1, col, array);

else display_error(UP);

break;

case DOWN:

if ((row+1 < = SIZE) & & (array[row+1][col] == 0))

swap(row, col, row+1, col, array);

else display_error(DOWN);

break;

case LEFT:

if ((col-1 > =0) & & (array[row][col-1] == 0))

swap(row, col, row, col-1, array);

else display_error(LEFT);

break;

case RIGHT:

if ((col+1 < = SIZE) & & (array[row][col+1] == 0))

swap(row, col, row, col+1, array);

else display_error(RIGHT);

break;

}

}

//********************************************************************

 

//********************************************************************

//Swap: Эта функция заменяет два значения двухмерным массивом.

//********************************************************************

void swap(int row, int col, int new_row, int new_col, int array[SIZE][SIZE]) {

int temp;

temp = array[row][col];

array[row][col] = array[new_row][new_col];

array[new_row][new_col] = temp;

}

 

//********************************************************************

//Swap2: Эта функция заменяет два значения одномерным массивом.

//********************************************************************

void swap2(int from, int to, int array[ARRAY_MAX+1]) {

int temp = array[from];

array[from] = array[to];

array[to] - temp;

}

 

//********************************************************************

//ERROR: Эта функция выводит сообщения об ошибке

//********************************************************************

void display_error(int n) {

LCD_Output(" ERROR: ");

switch(n) {

case LEFT:

LCD_output(" no move L");

break;

case RIGHT:

LCD_output(" no move R");

break;

case UP:

LCD_output(" no move U");

break;

case DOWN:

LCD_output(" no move D");

break;

}

pause();

}

//********************************************************************

 

//********************************************************************

//LCD_output: Эта функция выводит на дисплей строку

//********************************************************************

void LCD_output(char s[]) {

int n = 0;

while (s[n]! = '\0') {

LCD_char(s[n]);

++n;

}

}

 

//********************************************************************

//Pause: Функция реализует ожидание, пока игрок не нажмет кнопку

// " Выбор"

//********************************************************************

void pause() {

unsigned char с = ZERO;

LCD_output(" (Please press X)");

while (c! = S_BUTTON) {

c = PORTS;

с = c & 0x7C;

}

Clearscreen();

Reset_cursor();

}

 

//********************************************************************

//Delay: Эта функция вводит задержку на n мкс, если входная

// величина равна n

//********************************************************************

void delay(int usec) {

int i, j;

for (i=0; i< usec; i++) {

for (j=0; j < 7; j++) {}

}

}

 

//********************************************************************

//Initialize_LCD: Функция инициализирует ЖКД

//********************************************************************

void initialize_LCD(void) {

char temp = 0x00;

PORTDLC = 0xFF;

PORTDLC = PORTDLC & 0xEF; // сброс экрана (RESET = 0)

delay(2000); // задержка в 2 мс

PORTDLC = 0x7F; // выключение сброса

write(); //включение записи

command(0x80);

//установка текстового режима

data(0x0); //проверка установки слова

data(0x10);

command(0x40);

data(0x10); // устанавливается размер области текста (1E)

data(0x00); // - 0x1000

command(0x41);

//включается дисплей текста, курсор, выключается мигание

command(0x94);

command(0xA7); //курсор 8& #215; 8 точек

}

 

//********************************************************************

//Enable: Функция разрешает работу ИС

//********************************************************************

void enable(void) {

PORTDLC = PORTDLC | 0x04; // Установить 1 на линии enable

PORTDLC = PORTDLC & 0xFB; // Установить 0 на линии enable

}

 

//********************************************************************

//Disable: Функция запрещает работу ИС

//********************************************************************

void disable(void) {

PORTDLC = PORTDLC | 0x04;

}

 

//********************************************************************

//Command: Функция посылает команду отключения на ЖКД

//********************************************************************

void command(unsigned char n) {

status_wait();

PORTP = n;

PORTDLC = 0xFF;

PORTDLC = PORTDLC & 0xFE; // сброс записи

enable(); // сброс флага CE

delay(10); // задержка не менее 80 нс

disable(); // включение флага CE

}

 

//********************************************************************

//Data: Функция пересылает данные на ЖКД

//********************************************************************

void data(unsigned char n) {

status_wait();

PORTP = n;

PORTDLC = 0xFF;

PORTDLC = PORTDLC & 0xF7; // перевести C/D на низкий уровень

PORTDLC = PORTDLC & 0xFE; // перевести WR на низкий уровень

PORTDLC = PORTDLC & 0xFB;

delay(10);

disable();

}

 

//********************************************************************

//Write: Функция конфигурирует порт P как выходной

//********************************************************************

void write() {

DDRP = 0xFF;

}

 

//********************************************************************

//Read: Функция конфигурирует порт P как входной

//********************************************************************

void read() {

DDRP = 0x00;

}

 

//********************************************************************

//Status_wait: Создает соответствующие задержки между командами ЖКД

//********************************************************************

void status_wait() {

char temp = 0x00;

DDRP = 0x00;

PORTDLC = PORTDLC | 0x0F; // сбросить все

PORTDLC = PORTDLC & 0xFD; // сброс флага RD

enable();

delay(10);

while ((temp & 0x03)! = 0x03) {

temp = PORTP;

}

disable();

DDRP = 0xFF;

}

 

//********************************************************************

//LCD_char: Функция выводит ASCII код на экран ЖКД

//********************************************************************

void LCD_char(unsigned char n) {

data(n-0x20);

command(0xC0);

}

 

//********************************************************************

//Clearscreen: Функция очищает экран ЖКД

//********************************************************************

void Clearscreen() {

int i, j;

Reset_cursor();

for (i=0; i < 16; i++) for (j=0; j< 16; j++) LCD_char(' ');

Reset_cursor();

}

 

//********************************************************************

//Newline: Функция выводит пустую строку на экран ЖКД

//********************************************************************

void newline() {

int i;

for (i=0; i < 16; i++)

LCD_char(' ');

}

 

//********************************************************************

//Reset_cursor: Функция возвращает курсор ЖКД в начальную позицию

//********************************************************************

void Reset_cursor() {

data(0x00);

data(0x10);

command(0x24);

}

//********************************************************************

 






© 2023 :: MyLektsii.ru :: Мои Лекции
Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав.
Копирование текстов разрешено только с указанием индексируемой ссылки на источник.