LINUX.ORG.RU

Я неправильно понимаю булеву логику в Pascal?

 ,


0

1

Добрый день! Написал свою версию программы из учебника А.В. Столярова «Азы программирования» в которой можно передвигать звездочку по экрану терминала (2-е издание, глава 2.8.3 стр. 374).

program WonderingStar;
uses crt;
const
    message = '*';
    DelayDuration = 100;            {0.1 sec}

procedure GetKey(var code: integer);
var
    c: char;
begin
    c := ReadKey;
    if c = #0 then
        begin
        c := ReadKey;
        code := -ord(c)
        end
    else
        code := ord(c)
end;

procedure ShowMessage(x, y: integer; msg: string);
begin
    GotoXY(x, y);
    write(msg);
    GotoXY(1, 1)
end;

procedure ClearMessage(x, y: integer; msg: string);
var
    len, i: integer;
begin
    len := length(msg);
    GotoXY(x, y);
    for i := 1 to len do
        write(' ');
    GotoXY(1,1)
end;

procedure ScreenBoundariesCheck(var x, y: integer; msg: string; dx, dy: integer);
begin
    if (x + dx >= 1) and (x + dx <= ScreenWidth) then
        x := x + dx;
    if (y + dy >= 1) and (y + dy <= ScreenHeight) then
        y := y + dy
end;

procedure MoveMessage(var x, y: integer; msg: string; dx, dy: integer);
begin
    while true do
        begin
        ClearMessage(x, y, msg);
        ScreenBoundariesCheck(x, y, msg, dx, dy);
        if not (x = ScreenWidth) and not (y = ScreenHeight) then
            ShowMessage(x, y, msg);
        delay(DelayDuration);
        if KeyPressed then
            exit
        end
end;

var
    CurX, CurY, i: integer;
begin
    clrscr;
    CurX := (ScreenWidth - length(Message)) div 2;
    CurY := ScreenHeight div 2;
    ShowMessage(CurX, CurY, Message);
    while true do
        begin
        GetKey(i);
        case i of
            -72:        {down key}
                MoveMessage(CurX, CurY, Message, 0, -1);
            -80:        {up key}
                MoveMessage(CurX, CurY, Message, 0, 1);
            -75:        {left key}
                MoveMessage(CurX, CurY, Message, -1, 0);
            -77:        {right key}
                MoveMessage(CurX, CurY, Message, 1, 0);
            32:         {space key}
                MoveMessage(CurX, CurY, Message, 0, 0);
            27:         {finish (escape key)}
                break
            end
        end;
    clrscr
end.

В процедуре MoveMessage фрагмент на строке 53

    if not (x = ScreenWidth) and not (y = ScreenHeight) then
        ShowMessage(x, y, msg);

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

т.е., насколько я понимаю, я написал: «Если одновременно и X и Y принимают максимальное значение, то звёздочку не печатаем».

Однако после компиляции и запуска программы я обнаружил, что звёздочка не печатается во всей последней строке и во всем посдеднем столбце.

В то же время я обнаружил, что если в условии поменять and на or, т.е. написать «Если у нас либо X либо Y принимает максимальное значение, то звёздочку не печатаем», то всё заработает именно так, как я хочу: не будет печататься «нижний правый пиксель».

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

В чём я ошибаюсь?



Последнее исправление: KOMMUNIST90 (всего исправлений: 1)

т.е., насколько я понимаю, я написал: «Если одновременно и X и Y принимают максимальное значение, то звёздочку не печатаем».

Нет, вы написали «Если одновременно и X и Y не принимают максимальное значение». Скорее всего неверно было сформировано отрицание. Учите законы Де-Моргана.

X512 ★★★★★
()
Последнее исправление: X512 (всего исправлений: 1)
Ответ на: комментарий от X512

«Если одновременно и X и Y не принимают максимальное значение»

Верно, «Если одновременно и X и Y не принимают максимальное значение => печатаем сообщение, в противном случае не делаем ничего»

На практике же звёздочка не печатается во всей последней строке и во всем посдеднем столбце.

KOMMUNIST90
() автор топика
Ответ на: комментарий от KOMMUNIST90

«Если одновременно и X и Y принимают максимальное значение, то звёздочку не печатаем»

Отрицанием будет:

«Если X или Y не принимает максимальное значение, то звёздочку печатаем».

X and Y = not (not X or not Y)

Называется закон Де Моргана.

X512 ★★★★★
()

Некий Блез Паскаль тут нипричём. Надо только учитывать приоритет выполнения логических операций , чтобы правильно расставить скобки. Наивысший приоритет у операции НЕ (not), затем у И (and), затем у ИЛИ (or).

Partisan ★★★★
()
Ответ на: комментарий от KOMMUNIST90

«Если одновременно и X и Y не принимают максимальное значение

Эквивалентно «Если хотябы одно из значений X или Y принимает немаксимальное значение.»

Psilocybe ★★★★
()
Последнее исправление: Psilocybe (всего исправлений: 3)