Crie um programa Paint!


51

Introdução

Um dia, você estava mostrando ao seu filho como desenhar no computador. Você digita mspaint.exena barra de execução. Para seu horror, ele diz "Nenhum item corresponde à sua pesquisa". Você deve criar uma versão simples da tinta para que seu filho possa desenhar!

Desafio

Você deve criar um programa de desenho simples. Para fazer isso, abra uma janela de exibição branca (maior que 99x99 pixels). Sempre que o mouse for pressionado, altere o pixel em que o mouse está preto.

Isso é , então a resposta mais curta em bytes vence!


8
Precisa ser pixels? ou pode ser quadrados de 99x99?
fənɛtɪk

2
Por quanto tempo ele precisa ser executado?
Rɪᴋᴇʀ

2
Quando o TI-Basic Penfaz exatamente isso: o
Timtech

11
@Riker ele deve ser executado durante pelo menos 10 segundos, de preferência sempre
pydude

11
É maior que 99 × 99, portanto, precisamos usar três dígitos na notação decimal para cada dimensão? 99 × 100 ou 100 × 99 seriam válidos?
Sebastian Simon

Respostas:


86

Código de máquina 8086, 32 31 28 26 bytes

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

Assume a presença de uma placa gráfica VGA e de qualquer driver de mouse compatível com a Microsoft.

-2 bytes graças a @berendi!

captura de tela

Como funciona:

            |   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

É tudo o que há para isso. Nenhuma mágica envolvida, apenas algumas chamadas de função.


11
Código limpo, claro e inteligente. Muito bem feito! Não vejo em nenhum lugar isso pode ser otimizado ainda mais para o tamanho. Por alguma razão, quando tentei isso usando o driver CuteMouse, isso ocorre sem que o botão do mouse precise ser pressionado, mas isso pode ser apenas um problema, pois o CuteMouse não é 100% compatível com a Microsoft. Qual driver você usou para testar?
Cody Grey #

2
Hmm. Depois de executar o código com um depurador (DEBUG.COM antigo, é claro!), Parece que não há problema com o driver CuteMouse. Sem um botão pressionado, INT 33hestá retornando 0 in BX, e isso é diminuído para FFFFh conforme o esperado, mas uma linha ainda está sendo desenhada. Talvez isso ocorra porque o modo 11h possui apenas uma página de vídeo e o número de página inválido está sendo corrigido automaticamente? Estou testando no VM VirtualBox, então talvez isso seja algo que sua implementação do BIOS esteja fazendo.
Cody Gray

2
Parece que o VirtualBox é o culpado aqui, ele simplesmente ignora completamente o número da página: virtualbox.org/browser/vbox/trunk/src/VBox/Devices/Graphics/…
user5434231

2
O próprio Bill Atkinson ficaria orgulhoso disso. Esplêndido trabalho.
Wossname 23/04

4
-2 bytes removem o último int 0x10, jmpvoltando ao segundo int 0x10. O deslocamento em jmppermanece o mesmo, ajuste o endereço emmov dx
berendi - protestando

25

Zero, 10 bytes de zero

O Scratch foi praticamente projetado para coisas assim.

Experimente online!


Isso realmente faz pixels? Além disso, se você clicar com o mouse rápido e pressioná-lo um pouco, ele produzirá resultados diferentes (sem movê-lo, é claro). Eu acho que isso invalida isso.
Rɪᴋᴇʀ

19
Não são 10 bytes de rascunho, de acordo com a pontuação que usamos atualmente.
Okx

2
Você provavelmente deve usar o aplicativo scratchblocks para converter em texto ou o tamanho do arquivo SB2.
Matthew Roh

2
Estou usando a pontuação que usei nas respostas anteriores do Scratch. Alguém pode me vincular à pontuação atual? @Okx
dkudriavtsev

8
@ Mendeleev Não tenho certeza, mas ele provavelmente está se referindo a este sistema de pontuação do Scratch .
FreeAsInBeer

20

HTML + JavaScript (ES6), 66 64 62 bytes

HTML

<canvas id=c>

Javascript

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

Economizou 2 bytes graças a Gustavo Rodrigues e 2 bytes de Shaggy.

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>


Que tal <canvas id=c>?
Gustavo Rodrigues

2
Na verdade, isso coloca o ponto não onde meu cursor vai, mas no canto inferior direito da seta. Isso é intencional?
Anoplexian

Salve 2 bytes descartando o arquivo c.desde o início do seu JS. @ Anoplexian, esse é o corpo padrão que marginjoga fora algumas pixels.
Shaggy

4
Como eu faço isso funcionar? Estou clicando na área de resultados e não está fazendo nada.
numbermaniac

11
@ Anoplexian Esse é um problema conhecido; não há uma maneira confiável de obter a posição relativa do cursor do mouse em um elemento (poucas funções grandes específicas do navegador que falham quando um novo tipo de preenchimento de CSS é introduzido).
Wizzwizz4

17

C + Win32, 209 200 195 bytes

Obrigado, Cody e Quentin! Eu estava esperando para me livrar do, #include <windows.h>mas isso leva a todos os tipos de erros. Pelo menos, está funcionando corretamente com vários monitores ...

#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));}

Código anterior:

#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));}

insira a descrição da imagem aqui


2
Eu não posso testar agora, bu Eu acho que você pode mesclar a declaração de hdentro do forinicializador para salvar dois bytes :)
Quentin

Sei que este é o golfe código e pode ser desejável aqui, mas LOWORDe HIWORDse não a maneira correta para extrair coordenadas do cursor de um embalado LPARAM. Você deve estar usando GET_X_LPARAMe GET_Y_LPARAM, caso contrário, obterá resultados errados com vários monitores.
Cody Grey #

@ Quentin, que funcionará em c ++, mas não em c. Eu poderia ter usado c ++, mas então eu teria escrito o int mainque teria adicionado mais 4 bytes.
Johan du Toit

@ Cody, comentário justo. Não tenho um sistema de vários monitores para testar, mas você acha que o uso (short)LOWORD()e (short)HIWORD()resolveria o problema?
Johan du Toit

O que Quentin sugeriu funciona bem em qualquer versão moderna do C, incluindo o C99. Obviamente, você está usando o compilador C da Microsoft, que está preso na C89 / 90, com suas regras de escopo de variáveis ​​demente. C89 também é o motivo pelo qual você pode omitir o maintipo de retorno da função (por causa da intregra implícita ). O único problema é omitir o return 0;comportamento indefinido das causas em C89 e MSVC. Em C99 e C ++, você precisa de um tipo de retorno para main, mas o return 0;é implícito e, portanto, desnecessário. Bem, a linguagem não foi feita para o código de golfe. :-)
Cody Gray

10

Processando, 98 79 bytes

19 bytes salvos graças a @dzaima

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

Explicação (desatualizada)

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
}

clicketty clique


@ dzaima Eu não sabia o size(100,100);que não precisa ser mencionado, obrigado! (também não sei por que eu não vi o if(mousePressed)bit)
Kritixi Lithos

7

JavaScript ES6, 126 bytes

Testado em cromo.

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

Experimente online!

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 bytes

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

Isso usa a Glossbiblioteca (v1.11). Ele abre uma janela de tela cheia e pinta pixels pretos (na verdade, círculos com o raio 1) pressionando o botão esquerdo do mouse. Pressione ESCpara sair.

Como funciona:

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

Edit: @ cessou de girar no sentido contrário, disse-me sobre a versão mais recente do gloss, que economiza 5 bytes ao usar janelas de tela cheia. Obrigado!


FullScreené nulo em brilho> = 1.11, reduzindo a pontuação em 5. (Estou recebendo um erro unknown GLUT entry glutInit, mas provavelmente minha configuração de excesso simplesmente não funciona; nunca a usei nesta máquina.)
parou de girar no sentido contrário ao relógio

@ceasedtoturncounterclockwis: ah, obrigado pela dica. Eu tinha o 1.10.2.3 no meu sistema e agora atualizado para a versão mais recente.
Nimi

5

SmileBASIC 2, 52 51 bytes

Este é executado no pai do SmileBASIC, Petit Computer (e é um byte mais curto.)

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

Explicação:

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

Você pode economizar 1 byte, GPSET TCHX,TCHY:GOTO@Apois a cor padrão é 0 (transparente).
12Me21

4

Javascript + jQuery 138 bytes

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

Confira on-line!

Adicionar suporte de clicar e arrastar seria simples; no entanto, você definiria uma variável de acordo com as instruções e para reduzir o código, ele não é suportado: "Sempre que o mouse for pressionado, altere o pixel em que o mouse está preto" . Eu interpretei a instrução como um clickevento.


3
Hiya! Da próxima vez, você deve recuperar sua resposta antiga em vez de fazer uma nova resposta. Além disso, receio que isso funcione em um ambiente especificado - se for javascript vanilla, você precisará incluir a contagem de bytes do jQuery no seu envio. Você poderia chamar esse envio de "JavaScript + jQuery", e isso seria ótimo: lá você pode assumir que o jQuery está instalado. Como esta resposta está atualmente, é mais uma resposta "HTML", e não javascript.
Conor O'Brien

11
@ ConorO'Brien Vou fazer isso da próxima vez. Atualizei a resposta usando suas sugestões.
194 Neil

4

SpecBAS - 61 59 bytes

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

O preto já é a cor padrão da caneta, mas o fundo geralmente é um tom desagradável de cinza, então o CLS 15define para branco brilhante.

insira a descrição da imagem aqui


A maioria das variantes básicas não requer um espaço entre o número do comando e o código nessa linha.
Pavel

SpecBAS adiciona todos os espaços depois de bater retorno (incluindo GOTOtornar-se GO TO)
Brian

11
Mas você pode remover os espaços e ainda assim executar bem? Nesse caso, você não os conta.
Pavel

Se o usuário não se importa apenas de pintar de preto, por que ele se importaria com um fundo cinza?
Cees Timmerman

3

SmileBASIC, 70 58 53 Bytes

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

Explicado:

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 bytes

-20 bytes graças a @cfrick por apontar que eu posso usar usepara reduzir minha importação.

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

Usa a biblioteca Quil . Desenha um ponto sempre que o mouse é arrastado.

Basicamente, a resposta de processamento, já que Quil é um wrapper de processamento para 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))) 

insira a descrição da imagem aqui


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

@cfrick LOL, eu sempre esqueço useporque "não é apropriado". Obrigado.
precisa saber é o seguinte


2

Java 7, 353 bytes

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 e Python3, 82 bytes (ou 77?)

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

Usando o módulo Turtle, isso não é tão ruim :)

Ungolfed:

import turtle
turtle.up()

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

turtle.onscreenclick(fun)
turtle.mainloop()

Se não há problema em ter linhas entre os pontos, você pode realmente salvar 5 bytes:

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

da importação de tartarugas *; up (); onclick (lambda * x: goto (* x) ou dot (1)); done () #
1439

Isso é 70 bytes
innisfree:

2

Excel VBA, 62 bytes

Função de janela imediata VBE anônima que permite ao usuário desenhar em qualquer folha, simplesmente selecionando-a

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

Saída de amostra

insira a descrição da imagem aqui


1

HTML + Javascript, 152 148 bytes

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

1

Turing , 77 bytes

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 bytes

Diversão com 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 bytes

Este tenta compensar o padrão margindo <body>elemento, mas pode ser diferente nos navegadores e nas folhas de estilo do agente do usuário. Testado com sucesso no 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 bytes

Os pixels neste podem parecer maiores à medida que são desenhados nas coordenadas de meio pixel.

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 byte

Pt-Change(

Tenho certeza de que a maioria de vocês com TI pensa no Pencomando, mas acontece que não é tokenizado; portanto, faria mais sentido contar isso como 3 bytes. Você pode ler sobre a versão interativa Pt-Change(em http://tibasicdev.wikidot.com/pt-change


Isso não responde ao desafio: os cálculos da TI não podem lidar com a entrada do mouse, tanto quanto eu sei.
Grimmy #

2
@ Grimy Se você insistir, sempre pode usar a biblioteca usb8x para obter a entrada do mouse USB. Mas tenho certeza de que a navegação padrão do cursor será suficiente.
Timtech # 1

1

Lua (estrutura do love2d), 180 bytes

versão golfada

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

destroçado

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

muito fácil como funciona. Primeiro, algumas inicializações para tornar as coisas mais curtas. Depois disso, ele verifica se a mous é clicada e salva os pontos na matriz. Depois disso, ele desenha os pontos. Também define a cor para branco e preto, porque o padrão é o contrário :)
E aqui vem a imagem:

insira a descrição da imagem aqui


11
Acredite ou não, eu vim aqui para postar uma resposta usando o Love2d, pois só recentemente descobri e adorei, então marque com +1 o esforço! Enfim, acho que você pode reduzi-lo um pouco mais como este: o 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)endque resulta em 169 bytes!
precisa saber é o seguinte

11
Eu vim aqui o mesmo tipo de razão, bom ver que existem outras pessoas fora aqui que sabem que: D Obrigado :)
Lycea

1

Processando, 65 bytes

void draw(){if(mousePressed)line(mouseX,mouseY,pmouseX,pmouseY);}

empate mínimo


1

glslsandbox 232 bytes

Post antigo, mas achei isso interessante.
Como o processamento já foi feito, decidi fazer algo diferente.

Isso desenha se o mouse é pressionado ou não, então não o que o pydude pediu, mas quase.

#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);}

Experimente no glslsandbox


0

Processando, 93 bytes, 91 bytes se os espaços não contam

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

11
No PPCG, se não mencionado no desafio, espaços e tudo contam como normais (como bytes na codificação de escolha, por padrão UTF-8). Portanto, sua pontuação seria de 92 bytes, pois o 1º espaço não pode ser removido sem interromper o programa, mas o segundo espaço pode ser removido com segurança.
Dzaima 22/04

0

UCBlogo com wxWidgets, 65 bytes

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

Explicação (o código atribuído à variável buttonacté executado em cada clique do botão):

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

Pelo menos, acho que isso funciona. De acordo com a documentação , mas aparentemente a buttonactvariável só funciona em uma versão wxWidgets e estou lutando para criar o UCBLogo com wxWidgets em um Linux moderno (waddyamean você não pode usar um ponteiro paraint trás e trás?).

UCBlogo sem wxWidgets, 73 bytes

Para ver o efeito pretendido, você pode executar esta versão mais longa com um loop infinito.

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

Mas isso trava ucblogona minha máquina ... Parece uma condição de corrida.

UCBlogo, realmente trabalhando na minha máquina, 80 bytes

setbg 7 setpc 0 ht pu
while[1=1][setpos mousepos if[button?][pd] fd 1 pu wait 1]
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.