![]() Главная страница Случайная страница КАТЕГОРИИ: АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника |
Программный код. //Программа: Игра в 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); } //********************************************************************
|