Создайте программу Paint!


51

Введение

Однажды ты показывал своему ребенку, как рисовать на компьютере. Вы вводите mspaint.exeв строке запуска. К вашему ужасу, он говорит: «Ни один элемент не соответствует вашему поиску». Вы должны создать простую версию краски, чтобы ваш ребенок мог рисовать!

Вызов

Вы должны создать простую программу для рисования. Для этого откройте белое окно дисплея (размером более 99x99 пикселей). Каждый раз, когда мышь нажимается, измените пиксель, на котором она находится, на черный.

Это , поэтому выигрывает самый короткий ответ в байтах!


8
Это должны быть пиксели? или это могут быть квадраты 99х99?
fəˈnɛtɪk

2
Как долго это должно бежать?
Rɪᴋᴇʀ

2
Когда TI-Basic Penделает именно это: o
Timtech,

1
@Riker должен работать не менее 10 секунд, желательно вечно
pydude

1
Больше 99 × 99, поэтому нам нужно использовать три цифры в десятичной записи для каждого измерения? Будут ли действительными 99 × 100 или 100 × 99?
Себастьян Симон

Ответы:


86

8086 машинный код, 32 31 28 26 байт

00000000  b8 0f 00 cd 10 b8 02 10  ba 18 01 cd 10 b8 03 00  |................|
00000010  cd 33 4b b8 01 0c eb f3  3f 00                    |.3K.....?.|
0000001a

Предполагается наличие видеокарты VGA и любого совместимого с Microsoft драйвера мыши.

-2 байта благодаря @berendi!

Скриншот

Как это устроено:

            |   org 0x100
            |   use16
b8 0f 00    |       mov ax, 0x000f      ; set screen mode: 640x350 monochrome
cd 10       |       int 0x10            ; call video bios
b8 02 10    |       mov ax, 0x1002      ; set palette
ba 18 01    |       mov dx, palette     ; pointer to palette data
cd 10       |   @@: int 0x10            ; call video bios
b8 03 00    |       mov ax, 0x0003      ; get mouse position in (CX, DX) and button status in BL
cd 33       |       int 0x33            ; call mouse driver
4b          |       dec bx              ; if no buttons pressed, --BX = 0xFFFF (invalid page)
b8 01 0c    |       mov ax, 0x0c01      ; plot pixel with color AL at (CX, DX) in page BH
eb f3       |       jmp @b              ; repeat
3f 00       |   palette db 0x3f, 0x00   ; palette in 2:2:2 rgb. color 0 = white, 1 = black.
            |                           ; this should be a 17-byte struct, but we only care about the first two colors here

Это все, что нужно сделать. Никакой магии, только несколько вызовов функций.


1
Чистый, понятный и умный код. Очень красиво сделано! Я нигде не вижу, чтобы это можно было оптимизировать по размеру. По какой-то причине, когда я попытался сделать это с помощью драйвера CuteMouse, он рисует без необходимости удерживать нажатой кнопку мыши, но это может быть просто проблемой из-за того, что CuteMouse не на 100% совместим с Microsoft. Какой драйвер вы использовали для тестирования?
Коди Грей,

2
Хм. После запуска кода с помощью отладчика (конечно же, старого доброго DEBUG.COM!) Проблема с драйвером CuteMouse не возникает. Без удерживаемой кнопки INT 33hвозвращает 0 в BX, и это уменьшается до FFFFh, как и ожидалось, но линия все еще рисуется. Возможно, это связано с тем, что в режиме 11h имеется только одна страница видео, и номер неверной страницы автоматически исправляется? Я тестирую на VM VirtualBox, так что, возможно, это то, что делает его реализация BIOS.
Коди Грей,

2
Похоже , VirtualBox виноват здесь, он просто игнорирует номер страницы в целом: virtualbox.org/browser/vbox/trunk/src/VBox/Devices/Graphics/...
user5434231

2
Сам Билл Аткинсон гордился бы этим. Великолепная работа.
Wossname

4
-2 байта удаляют последний int 0x10, вместо этого jmpвозвращаются ко второму int 0x10. Смещение в jmpостается тем же, настроить адрес вmov dx
Беренди - протестуя

25

Scratch, 10 Scratch Bytes

Царапина была практически разработана для таких вещей.

Попробуйте онлайн!


Это действительно делает пиксели? Кроме того, если вы быстро щелкнете мышью, удерживая ее в течение некоторого времени, вы получите другие результаты (конечно, не перемещая ее). Я думаю, что это лишает законной силы это.
Rɪᴋᴇʀ

19
Это не 10 Scratch байтов, в соответствии с оценкой, которую мы используем в настоящее время.
Okx

2
Вам, вероятно, следует использовать приложение scratchblocks для преобразования в текст или размер файла SB2.
Мэтью Ро

2
Я использую оценку, которую я использовал с более ранними Скретч-ответами. Может кто-нибудь, пожалуйста, связать меня с текущей оценкой? @Okx
dkudriavtsev

8
@Mendeleev Я не уверен, но он, вероятно, имеет в виду эту систему оценки Scratch .
FreeAsInBeer

20

HTML + JavaScript (ES6), 66 64 62 байта

HTML

<canvas id=c>

JavaScript

onclick=e=>c.getContext`2d`.fillRect(e.x,e.y,1,1)

Сохранено 2 байта благодаря Густаво Родригесу и 2 байта от Шегги.

onclick=e=>c.getContext`2d`.fillRect(e.x,e.y,1,1)
/* This css isn't needed for the program to work. */
*{margin: 0}
#c{border:1px solid black}
<canvas id=c>


Как насчет <canvas id=c>?
Густаво Родригес

2
Это фактически ставит точку не там, где движется мой курсор, а справа внизу от стрелки. Это намеренно?
аноплексия

Сохраните 2 байта, опустив c.с начала вашего JS. @Anoplexian, это тело по умолчанию, marginотбрасывающее вещи на несколько пикселей.
Лохматый

4
Как мне сделать эту работу? Я нажимаю на область результатов, и она ничего не делает.
Numbermaniac

1
@Anoplexian Это известная проблема; нет надежного способа получить относительную позицию курсора мыши на элементе (если не считать больших функций, специфичных для браузера, которые не работают, когда вводится новый тип заполнения CSS).
wizzwizz4,

17

C + Win32, 209 200 195 байт

Спасибо, Коди и Квентин! Я надеялся избавиться от этого, #include <windows.h>но это приводит к всевозможным ошибкам. По крайней мере, он работает правильно с несколькими мониторами ...

#include<windows.h> 
struct{int h,m,w,x:16,y:16;}m;h;main(){for(h=CreateWindow("EDIT","",1<<28,0,0,199,199,0,0,0,0);GetMessage(&m,h,0,0);m.m^513?DispatchMessage(&m):SetPixel(GetDC(h),m.x,m.y,0));}

Предыдущий код:

#include<windows.h> 
main(){MSG m;HWND h;for(h=CreateWindow("EDIT","",1<<28,0,0,199,199,0,0,0,0);GetMessage(&m,h,0,0);m.message^513?DispatchMessage(&m):SetPixel(GetDC(h),LOWORD(m.lParam),HIWORD(m.lParam),0));}

введите описание изображения здесь


2
Я не могу проверить прямо сейчас, но я думаю, что вы можете объединить объявление hв forинициализаторе, чтобы сохранить два байта :)
Квентин

Я понимаю , что это код для гольфа и может быть желательными здесь, но LOWORDи HIWORDявляюсь не правильным способом извлечения координат курсора из упакованных LPARAM. Вы должны использовать GET_X_LPARAMи GET_Y_LPARAM, в противном случае вы получите неправильные результаты с несколькими мониторами.
Коди Грей,

@Quentin, это будет работать в c ++, но не в c. Я мог бы использовать c ++, но тогда я бы написал, int mainчто бы добавить еще 4 байта.
Йохан дю Туа

@ Коди, Честный комментарий. У меня нет мульти системы мониторинга для тестирования , но как вы думаете , с помощью (short)LOWORD()и (short)HIWORD()будете решать этот вопрос?
Йохан дю Туа

То, что предложил Квентин, прекрасно работает в любой современной версии C, включая C99. Конечно, вы используете компилятор Microsoft C, который застрял в C89 / 90, с его безумными правилами изменения области видимости. C89 также объясняет, почему вы можете опускать mainтип возвращаемого значения функции (из-за неявного intправила). Единственная проблема заключается в исключении return 0;причин неопределенного поведения в C89 и MSVC. В C99 и C ++ вам нужен тип возвращаемого значения для main, но return 0;он неявный и поэтому не нужен. Ну, язык не был создан для игры в гольф. :-)
Коди Грей,

10

Обработка 98 79 байт

19 байтов сохранено благодаря @dzaima

void setup(){background(-1);}void draw(){if(mousePressed)point(mouseX,mouseY);}

Объяснение (устарело)

void setup() {
  size(100,100);            // size of the sketch
  background(-1);           // set the background to white
                            // 1 byte shorter than background(255);
}

void draw(){}               // required for mousePressed to work

void mousePressed() {       // function that is called whenever the mouse is pressed
  point(mouseX, mouseY);    // draw a point at the mouse's coordinates
                            // the colour is set to black as default
}

щелчок мышью


@ Dzaima Я не знал size(100,100);, не должен быть упомянут, спасибо! (также я не знаю, почему я не видел if(mousePressed)бит)
Kritixi Lithos

7

JavaScript ES6, 126 байт

Проверено в хром.

onclick=e=>document.body.outerHTML+=`<a style=position:fixed;top:${e.y}px;left:${e.x}px;width:1px;height:1px;background:#000>`

Попробуйте онлайн!

onclick=e=>document.body.outerHTML+=`<a style=position:fixed;top:${e.y}px;left:${e.x}px;width:1px;height:1px;background:#000>`


7

Haskell, 189 184 170 169 байт

import Graphics.Gloss.Interface.Pure.Game
main=play FullScreen white 9[]Pictures(#)(\_->id)
EventKey(MouseButton LeftButton)Down _(x,y)#l=Translate x y(Circle 1):l
_#l=l

Это использует Glossбиблиотеку (v1.11). Он открывает полноэкранное окно и рисует черные пиксели (фактически круги с радиусом 1), нажимая левую кнопку мыши. Нажмите ESCдля выхода.

Как это устроено:

play                 -- handles the whole event handling, screen update, etc. process
    FullScreen       -- use a full screen window
    white            -- use a white background
    9                -- 9 simulation steps per second (see simulation handler below)
    []               -- the initial world state, an emtpy list of circles
    Pictures         -- a function to turn the world state into a picture.
                     -- The world state is a list of translated circles and
                     -- "Pictures" turns this list into a single picture
    (#)              -- event handler, see below
    (\_->id)         -- simulation step handler. Ignore time tick and return the
                     -- world state unchanged. More readable: "\tick world -> world"

EventKey ... # l=... -- if the left mouse button is pressed, add a circle with
                     -- radius 1 translated to the current position of the mouse
                     -- to the world state
_#l=l                -- on all other events do nothing

Редактировать: @ceased to turn counterclockwis рассказал мне о новой версии глянца, которая экономит 5 байт при использовании полноэкранных окон. Спасибо!


FullScreenявляется нулевым в глянце> = 1.11, уменьшая счет на 5. (Я получаю ошибку, unknown GLUT entry glutInitхотя, возможно, моя настройка перенасыщения просто не работает; никогда не использовала ее на этом компьютере.)
перестал вращаться против часовой стрелки

@ceasedtoturncounterclockwis: ах, спасибо за подсказку. У меня был 1.10.2.3 в моей системе, и теперь он обновлен до последней версии.
Nimi

5

SmileBASIC 2, 52 51 байт

Это один работает в папочке SmileBASIC в Пти компьютер (и один два байта короче.)

PNLTYPE"OFF
GPAGE 1GCLS 15@A
GPSET TCHX,TCHY
GOTO@A

Объяснение:

PNLTYPE"OFF       'turn off keyboard
GPAGE 1           'set graphics to lower screen
GCLS 15           'clear with color 15 (white)
@A                'loop begin
GPSET TCHX,TCHY   'set black pixel at draw location
GOTO@A            'loop

Вы можете сохранить 1 байт, выполнив, GPSET TCHX,TCHY:GOTO@Aтак как цвет по умолчанию - 0 (прозрачный).
12Me21

4

Javascript + JQuery 138 байт

d=$(document.body).click((e)=>d.append("<div style='background:black;width:5;height:5;position:fixed;top:"+e.pageY+";left:"+e.pageX+"'>"))

Проверьте это онлайн!

Добавление поддержки щелчка и перетаскивания было бы простым, однако вы бы задали переменную в соответствии с инструкциями и, чтобы сократить код, она не поддерживается: «Каждый раз, когда мышь нажимается, измените пиксель, на котором она находится, на черный» , Я истолковал инструкцию как clickсобытие.


3
Hiya! В следующий раз вы должны восстановить свой старый ответ, а не делать новый. Кроме того, я боюсь, что это должно работать в указанной среде - если это ванильный javascript, вам нужно будет включить количество байтов jQuery в ваше представление. Вы могли бы назвать это представление «JavaScript + jQuery», и это было бы хорошо: там вы могли бы предположить, что jQuery установлен. Как этот ответ в настоящее время стоит, это скорее ответ "HTML", а не javascript.
Конор О'Брайен,

1
@ ConorO'Brien Я сделаю это в следующий раз. Я обновил ответ, используя ваши предложения.
Нил

4

SpecBAS - 61 59 байт

1 CLS 15 
2 IF MOUSEBTN=1 THEN PLOT MOUSEx,MOUSEy
3 GO TO 2

Черный уже является цветом пера по умолчанию, но фон, как правило, имеет неприятный оттенок серого, поэтому CLS 15устанавливает его на ярко-белый.

введите описание изображения здесь


Большинство базовых вариантов не требуют пробела между номером команды и кодом в этой строке.
Павел

SpecBAS добавляет все пробелы после того, как вы нажали return (включая GOTOстановление GO TO)
Brian

1
Но можете ли вы удалить пробелы, и все же у вас все работает нормально? Если это так, вы их не считаете.
Павел

Если пользователь не против рисовать только черным, зачем ему серый фон?
Сис Тиммерман,

3

SmileBASIC, 70 58 53 байта

XSCREEN 4GCLS-1@L
TOUCH OUT,X,Y
GPSET X,Y+240,0GOTO@L

Разъяснение:

XSCREEN 4 'display one graphics page on both screens
GCLS -1 'fill screen with white
@L 'loop
TOUCH OUT,X,Y 'get touch location
GPSET X,Y+240,0 'draw black pixel at touch position, offset by the height of the top screen.
GOTO @L 'loop

3

Clojure, 91 71 байт

-20 байт спасибо @cfrick за указание, что я могу использовать useдля сокращения моего импорта.

(use 'quil.core)(defsketch P :mouse-dragged #(point(mouse-x)(mouse-y)))

Использует библиотеку Quil . Рисует точку всякий раз, когда мышь перетаскивают.

В основном ответ на процессинг, поскольку Quil - это оболочка для обработки Clojure.

(q/defsketch P ; Start a new drawing

             :mouse-dragged ; Attach a mouse drag listener
             ; that draws a point at the current mouse location
             #(q/point (q/mouse-x) (q/mouse-y))) 

введите описание изображения здесь


71:(use 'quil.core)(defsketch P :mouse-dragged #(point(mouse-x)(mouse-y)))
cfrick

@cfrick LOL, я всегда забываю, useпотому что это "не правильно". Спасибо.
Carcigenicate


2

Java 7, 353 байта

import java.awt.*;import java.awt.event.*;class M{static int x,y;public static void main(String[]a){Frame f=new Frame(){public void paint(Graphics g){g.drawLine(x,y,x,y);}};f.addMouseListener(new MouseAdapter(){public void mousePressed(MouseEvent e){x=e.getX();y=e.getY();f.repaint(x,y,1,1);}});f.setBackground(Color.WHITE);f.resize(500,500);f.show();}}

Ungolfed:

import java.awt.*;
import java.awt.event.*;

class M {
    //store the last point
    static int x, y;
    public static void main(String[] a) {
        Frame f = new Frame() {
            @Override
            public void paint(Graphics g) {
                g.drawLine(x, y, x, y);
            }
        }
        f.addMouseListener(new MouseAdapter() {
            @Override
            public void mousePressed(MouseEvent e) {
                x = e.getX();
                y = e.getY();
                //repaint only the "new pixel"
                f.repaint(x, y, 1, 1);
            }
        });
        //default background is grey
        f.setBackground(Color.WHITE);
        f.resize(500, 500);
        f.show();
    }
}

2

Python2 и Python3, 82 байта (или 77?)

from turtle import *;up();onscreenclick(lambda x,y: goto(x,y)or dot(1));mainloop()

Используя модуль Turtle, это не так уж плохо :)

Ungolfed:

import turtle
turtle.up()

def fun(x, y):
    turtle.goto(x,y)
    turtle.dot(1)

turtle.onscreenclick(fun)
turtle.mainloop()

Если между точками все в порядке, вы можете сохранить 5 байтов:

from turtle import *;onscreenclick(lambda x,y: goto(x,y)or dot(1));mainloop()

от импорта черепахи *; up (); onclick (лямбда * x: goto (* x) или точка (1)); done ()
innisfree

Это 70 байт
innisfree

2

Excel VBA, 62 байта

Функция анонимного непосредственного окна VBE, которая позволяет пользователю рисовать на любом листе, просто выбрав его

Cells.RowHeight=48:Do:DoEvents:Selection.Interior.Color=0:Loop

Пример вывода

введите описание изображения здесь


1

HTML + Javascript, 152 148 байт

<body onclick="document.body.innerHTML+='<x style=position:fixed;width:1;height:1;left:'+event.clientX+';top:'+event.clientY+';background:#000;>'"/>

1

Тьюринг , 77 байтов

var x,y,b:int loop mousewhere(x,y,b)if b=1then drawdot(x,y,1)end if end loop

Ungolfed:

var x,y,b : int      
loop
  mousewhere(x,y,b)  % Set (x,y) to mouse co-ords, and b to 1 or 0 indicating if the button is pressed
  if b=1 then
    drawdot(x,y,1)  % Draw a black pixel at (x,y)
  end if
end loop

1

HTML + CSS + JavaScript (ES6), 8 + 31 + 64 = 103 байта

Весело с CSS box-shadow!

s='0 0 0',onclick=e=>p.style.boxShadow=s+=`,${e.x}px ${e.y}px 0`
*{margin:0;width:1px;height:1px
<p id=p>

HTML + CSS + JavaScript (ES6), 8 + 22 + 69 = 99 байт

Это один из попыток смещения по умолчанию marginв <body>элементе, но она может быть разной в разных браузерах и таблицы стилей агента пользователя. Успешно протестировано в Chrome.

s='0 0 0',onclick=e=>p.style.boxShadow=s+=`,${e.x-8}px ${e.y-16}px 0`
*{width:1px;height:1px
<p id=p>

HTML + CSS + JavaScript (ES6), 8 + 18 + 69 = 95 байт

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

s='0 0 0',onclick=e=>p.style.boxShadow=s+=`,${e.x}px ${e.y}px 0 .5px`
*{margin:0;width:0
<p id=p>


1

TI-Basic, 1 байт

Pt-Change(

Я уверен, что большинство из вас с TI calcs подумали об этой Penкоманде, но оказывается, что она не токенизирована, поэтому было бы разумнее считать это как 3 байта. Вы можете прочитать об интерактивной версии Pt-Change(на http://tibasicdev.wikidot.com/pt-change


Это не отвечает на вызов: насколько я знаю, TI Calcs не может обрабатывать ввод с помощью мыши.
Grimmy

2
@Grimy Если вы настаиваете, вы всегда можете использовать библиотеку usb8x, чтобы получить ввод USB-мыши. Но я уверен, что навигации по умолчанию будет достаточно.
Timtech

1

Lua (love2d Framework), 180 байт

версия для гольфа

l=love v,g,m,p=255,l.graphics,l.mouse,{}d=m.isDown function l.draw()g.setBackgroundColor(v,v,v)if d(1)or d(2)then p[#p+1],p[#p+2]=m.getPosition()end g.setColor(0,0,0)g.points(p)end

ungolfed

l=love 
v,g,m,p=255,l.graphics,l.mouse,{}
d=m.isDown 
function l.draw()
  g.setBackgroundColor(v,v,v)
  if d(1)or d(2)then 
    p[#p+1],p[#p+2]=m.getPosition()
  end 
  g.setColor(0,0,0)
  g.points(p)
end

довольно легко, как это работает. Сначала несколько инициализаций, чтобы сделать вещи короче. После этого он проверит щелчок мышью и сохранит точки в массив. После этого он рисует точки. Также он устанавливает цвет на белый и черный, потому что по умолчанию все наоборот :)
И вот картинка:

введите описание изображения здесь


1
Хотите верьте, хотите нет, но я пришел сюда, чтобы опубликовать ответ, используя Love2d, поскольку я только недавно узнал об этом и полюбил его, поэтому +1 за приятные усилия! Во всяком случае, я думаю, что вы можете сократить его немного больше, как это: l=love v,g,m,p=255,l.graphics,l.mouse,{}function l.draw()g.setBackgroundColor(v,v,v)if m.isDown(1)then p[#p+1],p[#p+2]=m.getPosition()end g.setColor(0,0,0)g.points(p)endэто приводит к 169 байтов!
DimP

1
Я приехал сюда по той же причине, приятно видеть, что здесь есть другие люди, которые знают это: D Спасибо :)
Lycea


1

glslsandbox 232 байта

Старый пост, но нашел это интересным.
Так как обработка уже была сделана, я решил сделать что-то другое.

Это рисует, нажата ли мышь или нет, поэтому не то, о чем просил pydude, а почти.

#ifdef GL_ES
precision lowp float;
#endif
uniform float time;uniform vec2 mouse,resolution;uniform sampler2D t;void main(){vec2 f=gl_FragCoord.xy,r=resolution;gl_FragColor=vec4(time<2.||length(f-mouse*r)>2.&&texture2D(t,f/r).x>.1);}

Попробуйте это на glslsandbox


0

Обработка, 93 байта, 91 байт, если пробелы не учитываются

void setup(){size(100,100);background(-1);}void draw(){if(mousePressed) point(mouseX,mouseY);}

1
В PPCG, если не упомянуто в вызове, пробелы и все считаются как обычно (как байты в выбранной кодировке, по умолчанию UTF-8). Таким образом, ваш счет будет 92 байта, поскольку 1-й пробел не может быть удален без нарушения программы, но второй пробел может быть безопасно удален.
Дзайма

0

UCBlogo с wxWidgets, 65 байт

setbg 7
setpc 0
ht
pu
make "buttonact[setpos clickpos pd fd 1 pu]

Пояснение (код, присвоенный переменной buttonact, выполняется при каждом нажатии кнопки):

SetBackground 7 ; white
SetPenColor 0 ; black
HideTurtle
PenUp
make "buttonact [
  SetPos ClickPos
  PenDown
  Forward 1
  PenUp
]

По крайней мере, я думаю, что это работает. Это должно в соответствии с документацией , но, очевидно, buttonactпеременная работает только в сборке wxWidgets, и я изо всех сил пытаюсь собрать UCBLogo с wxWidgets в современном Linux (waddyamean, вы не можете привести указатель intи обратно?).

UCBlogo без wxWidgets, 73 байта

Чтобы увидеть ожидаемый эффект, вы можете запустить эту более длинную версию с бесконечным циклом.

setbg 7 setpc 0 ht pu
while[1=1][setpos mousepos if[button?][pd] fd 1 pu]

Но это вылетает ucblogoна моей машине ... Похоже на состояние гонки.

UCBlogo, фактически работает на моей машине, 80 байтов

setbg 7 setpc 0 ht pu
while[1=1][setpos mousepos if[button?][pd] fd 1 pu wait 1]
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.