Блог пользователя x-firdavs.95

Автор x-firdavs.95, 10 лет назад, По-русски

Hi, I'm trying to solve problem E and I from this problem set: http://codeforces.com/gym/100463/attachments/download/2554/michigan-invitational-programming-contest-en.pdf

Currently, I have no idea how to solve them. I hope you guys can give me some hints. Thanks.

Полный текст и комментарии »

  • Проголосовать: нравится
  • 0
  • Проголосовать: не нравится

Автор x-firdavs.95, 10 лет назад, По-русски

Сегодня напишем в текстовом режиме с использованием прерываний BIOS и DOS змейку на Assembler. Для этого нужно знать основы, уметь ассемблировать (Tasm) и компоновать (Tlink) код.

Для начала напишем основу — змейку, которая перемещается в одном направлении по игровому полю. Змейка будет состоять из символа "*", координаты каждого символа хранятся в памяти.

model	small

.data					;Сегмент данных. Храним координаты тела змейки
snake	dw 0000h
        dw 0001h
        dw 0002h
        dw 0003h
        dw 0004h
        dw 7CCh dup('?')

.stack 100h

.code
;В начале сегмента кода будем размещать процедуры
delay proc
        push cx
    mov ah,0
    int 1Ah 
    add dx,3
    mov bx,dx
repeat:   
    int 1Ah
    cmp dx,bx
    jl repeat
    pop cx
    ret
delay endp

start:
    mov ax,@data
    mov ds,ax
    mov es,ax

    mov ax,0003h
    int	10h 			;Очищаем игровое поле

    mov cx,5
    mov ax,0A2Ah
    int 10h 			;Выводим змейку из 5 символов "*"


    mov si,8			;Индекс координаты символа головы
    xor di,di			;Индекс координаты символа хвоста
    mov cx,0001h		;Регистр cx используем для управления головой. При сложении от значения cx будет изменяться координата x или y

main:				;Основной цикл
    call delay
        xor bh,bh
    mov ax,[snake+si]		;Берем координату головы из памяти
    add ax,cx		        ;Изменяем координату x
    inc si				
    inc si
    mov [snake+si],ax		;Заносим в память новую координату головы змеи
    mov dx,ax			
    mov ax,0200h
    int 10h 			;Вызываем прерывание. Перемещаем курсор
    mov ah,02h
    mov dl,002Ah
    int 21h			;Прерывание выводит символ '*'
    
    mov ax,0200h 		
    mov dx,[snake+di]
    int 10h
    mov ax,0200h
    mov dl,0020h
    int 21h			;Выводим пробел, тем самым удаляя хвост
    inc di
    inc di
jmp main
end	start        

Добавим процедуру «key_press» обработки нажатия клавиши и присваивания значения регистру CX, отвечающему за направление головы.

Управление стрелками.

key_press

key_press proc
    mov ax, 0100h
    int 16h
    jz en 			;Без нажатия выходим
    xor ah, ah
    int 16h
    cmp ah, 50h
    jne up
    cmp cx,0FF00h		;Сравниваем чтобы не пойти на себя
    je en
    mov cx,0100h
    jmp en
up:	cmp ah,48h
    jne left
    cmp cx,0100h
    je en
    mov cx,0FF00h
    jmp en
left: cmp ah,4Bh
    jne right
    cmp cx,0001h
    je en
    mov cx,0FFFFh
    jmp en
right: cmp cx,0FFFFh
    je en
    mov cx,0001h
en:
    ret
key_press endp

Вызовем её сразу после вызова процедуры delay:

main:
    call delay
    call key_press

Накормим змейку, создаём процедуру «add_food». Эта процедура будет на игровом поле размещать еду, символы "$". В качестве случайных чисел будем брать время.

add_food

add_food proc
sc:	
    inc bl              ;В регистре BL рандомное число
    cmp bx,50h    ;Проверяем границу числа
    jng ex
    shr bl,1           ;Если больше, делим на 2 логическим сдвигом
    jmp sc
ex:
    mov dl,bl         ;Запись координаты
sc2:	
    cmp bx,19h
    jng ex2
    shr bl,2
    jmp sc2
ex2:
    mov dh,bl         ;Запись координаты
    mov ax,0200h
    int 10h
    mov ax,0800h
    int 10h
    cmp al,2Ah       ;Проверяем пустое ли место
    je sc
    cmp al,40h      
    je sc                  ;Если нет повторяем
    mov ax,0200h
    mov dl,0024h
    int 21h
    ret
add_food endp

Вызовем 1 раз в начале.

mov bl,51h
    call add_food
main:

Делаем проверку, съела змея еду или нет. Если съела, вызываем процедуру «add_food» и не удаляем хвост.

Проверку добавляем в код перед выводом символа головы:

mov ah,02h
    int 10h 			;Вызываем прерывание. Перемещаем курсор

    mov ax,0800h
    int 10h                     ;Читает символ 
    mov dh,al

    mov ah,02h
    mov dl,002Ah
    int 21h 			;Прерывание выводит символ '*'

    cmp dh,24h
    jne next
    call add_food
    jmp main
next:	

Усложним игру. После того, как питон съест 5 символов, в хвосте будет появляться символ "@". Пишем счетчик и вывод символа:

shit

;В сегмент данных добавим строчку
.data
tick	dw 0			;Счетчик
--------------------------------------------------------------------

    cmp dh,24h
    jne next

    push cx				;В стек регистр
    mov cx,[tick]
    inc cx
    cmp cx,5
    jne exl
    xor cx,cx
    mov ax,0200h 		
    mov dx,[snake+di-2]
    int 10h
    mov ax,0200h
    mov dl,0040h
    int 21h
exl:mov [tick],cx
    pop cx

    call add_food
    jmp main
next:	

Какая игра без Game Over. Пишем процедуру проверки границы поля, а также врезание в себя и символ "@".

game_over

game_over proc
;Проверяем границы
    cmp dl,50h
    je exit
    cmp dl,0
    jl exit
    cmp dh,0
    jl exit
    cmp dh,19h
    je exit
;Проверяем символы
    cmp al,2Ah
    je exit
    cmp al,40h
    je exit
    jmp good
exit: 
    mov ax,4c00h
    int 21h
good:
    ret
game_over endp

Вызываем её после считывания символа:

mov ax,0800h
    int 10h 			;Считываем символ

    call game_over

    mov dh,al

Немного магии добавляем после инкремента индексов.

magic

    inc si				
    inc si
    cmp si,7CAh
    jne nex
    xor si,si
nex:	

---------------------------------------------------------------------

    inc di
    inc di
    cmp di,7CCh
    jne main
    xor di,di

Ну вот и всё, также можно добавить меню с выбором уровня, паузу, заставку Game Over, счет очков.

По ссылке архив с исходным кодом, exe'шником и DosBox для тех, у кого не запустится.

Good Luck!!!

Полный текст и комментарии »

  • Проголосовать: нравится
  • -22
  • Проголосовать: не нравится

Автор x-firdavs.95, 11 лет назад, По-русски

Самое простое это добавление библиотеки algorithm, Example:

#include <iostream>
#include <algorithm>
using namespace std;

int main()
{
    int a[100];
    /*--------------------
    --------------------
    --------------------*/

    //кароче мы обявляем массив вводим его и после просто используем sort(begin, end); и всё
    sort(a, a + n); //n здесь количество элементов массива

    /*--------------------
    --------------------
    --------------------*/
     
    return 0;
}

Просто здесь я полностью не описал sort() Потому что для просто сортировки и этого хватает!

Полный текст и комментарии »

  • Проголосовать: нравится
  • -34
  • Проголосовать: не нравится