¡Crea un programa Paint!


51

Introducción

Un día, le mostrabas a tu hijo cómo dibujar en una computadora. Escribe mspaint.exeen la barra de ejecución. Para su horror, dice "Ningún elemento coincide con su búsqueda". ¡Debes crear una versión simple de pintura para que tu hijo pueda dibujar!

Desafío

Debe crear un programa de dibujo simple. Para hacer esto, abra una ventana de visualización blanca (más grande que 99x99 píxeles). Cada vez que se presiona el mouse hacia abajo, cambie el píxel en el que se encuentra el mouse a negro.

Este es el , ¡así que la respuesta más corta en bytes gana!


8
¿Tiene que ser píxeles? o puede ser 99x99 cuadrados?
fəˈnɛtɪk

2
¿Cuánto tiempo necesita correr?
Rɪᴋᴇʀ

2
Cuando TI-Basic Penhace exactamente esto: o
Timtech

1
@Riker debería funcionar durante al menos 10 segundos, preferiblemente para siempre
pydude

1
¿Es mayor que 99 × 99 solo para que tengamos que usar tres dígitos en notación decimal para cada dimensión? ¿Serían válidos 99 × 100 o 100 × 99?
Sebastian Simon

Respuestas:


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

Asume la presencia de una tarjeta gráfica VGA y cualquier controlador de mouse compatible con Microsoft.

-2 bytes gracias a @berendi!

captura de pantalla

Cómo 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

Eso es todo al respecto. No hay magia involucrada, solo algunas llamadas a funciones.


1
Código limpio, claro e inteligente. ¡Muy bien hecho! No veo en ninguna parte esto se puede optimizar aún más para el tamaño. Por alguna razón, cuando probé esto usando el controlador CuteMouse, esto se dibuja sin tener que mantener presionado el botón del mouse, pero eso puede ser un problema con que CuteMouse no sea 100% compatible con Microsoft. ¿Qué controlador usaste para probar?
Cody Gray el

2
Hmm Después de ejecutar el código con un depurador (¡buen viejo DEBUG.COM, por supuesto!), Parece que no es un problema con el controlador CuteMouse. Sin un botón presionado, INT 33hestá devolviendo 0 in BX, y esto se reduce a FFFFh como se esperaba, pero todavía se está dibujando una línea. ¿Quizás esto se deba a que el modo 11h solo tiene una página de video y el número de página no válido se está arreglando automáticamente? Estoy probando en VM VirtualBox, así que tal vez eso es algo que está haciendo su implementación de BIOS.
Cody Gray el

2
Parece que VirtualBox tiene la culpa aquí, simplemente ignora el número de página por completo: virtualbox.org/browser/vbox/trunk/src/VBox/Devices/Graphics/…
user5434231

2
El propio Bill Atkinson estaría orgulloso de esto. Espléndido trabajo.
Wossname

44
-2 bytes eliminan el último int 0x10, de jmpvuelta al segundo en su int 0x10lugar. La compensación jmpsigue siendo la misma, ajusta la dirección enmov dx
berendi - protestando el

25

Scratch, 10 bytes Scratch

Scratch fue prácticamente diseñado para cosas como esta.

Pruébalo en línea!


¿Esto realmente hace píxeles? Además, si hace clic rápido con el mouse en lugar de mantenerlo presionado por un momento, produce resultados diferentes (sin moverlo, por supuesto). Creo que eso invalida esto.
Rɪᴋᴇʀ

19
Esto no es 10 bytes Scratch, de acuerdo con la puntuación que usamos actualmente.
Okx

2
Probablemente deberías usar la aplicación scratchblocks para convertir a texto o el tamaño del archivo SB2.
Matthew Roh

2
Estoy usando la puntuación que usé con las respuestas anteriores de Scratch. ¿Alguien puede vincularme a la puntuación actual? @Okx
dkudriavtsev

8
@Mendeleev No estoy seguro, pero probablemente se esté refiriendo a este sistema de puntuación 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)

Ahorró 2 bytes gracias a Gustavo Rodrigues y 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>


¿Qué tal <canvas id=c>?
Gustavo Rodrigues

2
En realidad, esto coloca el punto no donde va mi cursor, sino a la parte inferior derecha de la flecha. ¿Es esto intencional?
Anoplexian

Ahorre 2 bytes descartando c.desde el inicio de su JS. @Anoplexian, ese es el cuerpo predeterminado que marginarroja cosas por unos pocos píxeles.
Shaggy

44
¿Cómo hago para que esto funcione? Estoy haciendo clic en el área de resultados y no está haciendo nada.
numbermaniac

1
@Anoplexian Ese es un problema conocido; no hay una manera confiable de obtener la posición relativa del cursor del mouse sobre un elemento (excepto las funciones grandes específicas del navegador que fallan cuando se introduce un nuevo tipo de relleno CSS).
wizzwizz4

17

C + Win32, 209 200 195 bytes

Gracias, Cody y Quentin! Tenía la esperanza de deshacerme de #include <windows.h>esto, pero esto conduce a todo tipo de errores. Al menos funciona correctamente con varios 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));}

ingrese la descripción de la imagen aquí


2
No puedo probar ahora, pero creo que puedes fusionar la declaración hen el forinicializador para guardar dos bytes :)
Quentin

Sé que esto es un código de golf y puede ser deseable aquí, pero LOWORDy HIWORDson no la forma correcta para extraer las coordenadas del cursor de un abarrotado LPARAM. Debería estar usando GET_X_LPARAMy GET_Y_LPARAM, de lo contrario, obtendrá resultados incorrectos con varios monitores.
Cody Gray el

@Quentin, eso funcionará en c ++ pero no en c. Podría haber usado c ++ pero luego habría escrito int mainlo que habría agregado 4 bytes más.
Johan du Toit

@Cody, comentario justo. No tengo un sistema de monitores múltiples para probar, pero ¿crees que usarlo (short)LOWORD()y (short)HIWORD()resolvería el problema?
Johan du Toit

Lo que Quentin sugirió funciona bien en cualquier versión moderna de C, incluido C99. Por supuesto, está utilizando el compilador C de Microsoft, que está atascado en C89 / 90, con sus reglas de alcance variables dementes. C89 también es la razón por la que puede omitir el maintipo de retorno de la función (debido a la intregla implícita ). El único problema es omitir las return 0;causas de comportamiento indefinido en C89 y MSVC. En C99 y C ++, necesita un tipo de retorno para main, pero return 0;es implícito y, por lo tanto, innecesario. Bueno, el lenguaje no fue hecho para golf de código. :-)
Cody Gray

10

Procesamiento, 98 79 bytes

19 bytes guardados gracias a @dzaima

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

Explicación (obsoleta)

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
}

clicketket clic


@dzaima No sabía size(100,100);que no tiene que mencionarse, ¡gracias! (también no sé por qué no vi la if(mousePressed)parte)
Kritixi Lithos

7

JavaScript ES6, 126 bytes

Probado en cromo.

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

Pruébalo en línea!

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 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

Esto usa la Glossbiblioteca (v1.11). Abre una ventana de pantalla completa y pinta píxeles negros (de hecho, círculos con radio 1) presionando el botón izquierdo del mouse. Presione ESCpara salir.

Cómo 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

Editar: @ceased to turn counterclockwis me contó sobre la versión más nueva de gloss que ahorra 5 bytes al usar ventanas de pantalla completa. ¡Gracias!


FullScreenes nulo en brillo> = 1.11, lo que reduce la puntuación en 5. (Sin unknown GLUT entry glutInitembargo, obtengo un error , pero probablemente mi configuración de exceso simplemente no funciona; nunca lo usé en esta máquina).
dejó de girar en sentido antihorario el

@ceasedtoturncounterclockwis: ah, gracias por la pista. Tenía 1.10.2.3 en mi sistema y ahora actualicé a la última versión.
nimi

5

SmileBASIC 2, 52 51 bytes

Este se ejecuta en el papá de SmileBASIC, Petit Computer (y es un byte más corto).

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

Explicación:

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

Puede guardar 1 byte haciendo GPSET TCHX,TCHY:GOTO@Aya que el color predeterminado es 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+"'>"))

¡Compruébalo en línea!

Agregar soporte para hacer clic y arrastrar sería simple, establecería una variable, sin embargo, según las instrucciones y para acortar el código, no es compatible, "Cada vez que se presiona el mouse, cambie el píxel que está en negro". . Interpreté la instrucción como un clickevento.


3
Hola La próxima vez, debe recuperar su respuesta anterior en lugar de hacer una nueva respuesta. Además, me temo que esto debe funcionar en un entorno específico: si se trata de JavaScript vainilla, deberá incluir el recuento de bytes de jQuery con su envío. Podría llamar a este envío "JavaScript + jQuery", y eso estaría bien: allí podría asumir que jQuery está instalado. Tal como está actualmente esta respuesta, es más una respuesta "HTML", no javascript.
Conor O'Brien

1
@ ConorO'Brien Me aseguraré de hacerlo la próxima vez. Actualicé la respuesta usando sus sugerencias.
Neil

4

SpecBAS - 61 59 bytes

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

El negro ya es el color predeterminado del bolígrafo, pero el fondo suele ser un tono gris desagradable, por CLS 15lo que lo establece en blanco brillante.

ingrese la descripción de la imagen aquí


La mayoría de las variantes básicas no requieren un espacio entre el número de comando y el código en esa línea.
Pavel

SpecBAS agrega todos los espacios después de presionar retorno (incluido el GOTOdevenir GO TO)
Brian

1
Pero, ¿puedes eliminar los espacios y aún así hacerlo funcionar bien? Si es así, no los cuentas.
Pavel

Si al usuario no le importa pintar solo con negro, ¿por qué le importaría un fondo gris?
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 gracias a @cfrick por señalar que puedo usar usepara reducir mi importación.

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

Utiliza la biblioteca Quil . Dibuja un punto cada vez que se arrastra el mouse.

Básicamente, la respuesta de procesamiento, ya que Quil es un contenedor de procesamiento 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))) 

ingrese la descripción de la imagen aquí


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

@cfrick LOL, siempre me olvido useporque "no es apropiado". Gracias.
Carcigenicate

3

Tcl / Tk, 45 46 51 57

gri [can .c]
bind . <1> {.c cr o %x %y %x %y}

pentagrama


Ese es un pentograma fugoso
Johan

1
@JohanduToit: ¿No te gustan las estrellas?
sergiol

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

Sin golf:

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 y Python3, 82 bytes (¿o 77?)

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

Usando el módulo Turtle, esto no es tan malo :)

Sin golf:

import turtle
turtle.up()

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

turtle.onscreenclick(fun)
turtle.mainloop()

Si está bien tener líneas entre los puntos, en realidad puede guardar 5 bytes:

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

desde la importación de tortuga *; arriba (); onclick (lambda * x: goto (* x) o dot (1)); hecho ()
innisfree

Eso es 70 bytes
innisfree

2

Excel VBA, 62 bytes

Función de ventana inmediata anónima VBE que permite al usuario dibujar en cualquier hoja simplemente seleccionándola

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

Salida de muestra

ingrese la descripción de la imagen aquí


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

Sin golf:

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

Diversión con 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

Éste intenta compensar el valor predeterminado margindel <body>elemento, pero puede ser diferente en los navegadores y las hojas de estilo de agente de usuario. Probado con éxito en 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

Los píxeles en este pueden aparecer más grandes a medida que se dibujan en coordenadas de medio píxel.

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(

Estoy seguro de que la mayoría de ustedes con TI calcs pensó en el Pencomando, pero resulta que no está tokenizado, por lo que tendría más sentido contarlo como 3 bytes. Puede leer sobre la versión interactiva de Pt-Change(en http://tibasicdev.wikidot.com/pt-change


Esto no responde al desafío: TI calcs no puede manejar la entrada del mouse, que yo sepa.
Grimmy

2
@Grimy Si insiste, siempre puede usar la biblioteca usb8x para obtener la entrada del mouse USB. Pero estoy seguro de que la navegación predeterminada del cursor será suficiente.
Timtech

1

Lua (marco love2d), 180 bytes

versión de golf

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

sin golf

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

Bastante fácil cómo funciona. Primero unas pocas inicializaciones para acortar las cosas. Después, comprobará que se hace clic en el mouse y guarda los puntos en la matriz. Después de eso dibuja los puntos. También establece el color en blanco y negro porque el valor predeterminado es al revés :)
Y aquí viene la imagen:

ingrese la descripción de la imagen aquí


1
Lo creas o no, vine aquí para publicar una respuesta usando Love2d, ya que recientemente me enteré y me encantó, ¡así que +1 por el buen esfuerzo! De todos modos, creo que puedes acortarlo un poco más de esta manera: ¡lo 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 da como resultado 169 bytes!
DimP

1
Vine aquí por la misma razón, me
alegra

1

Procesando, 65 bytes

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

dibujo mínimo


1

glslsandbox 232 bytes

Publicación anterior pero me pareció interesante.
Como el procesamiento ya se realizó, decidí hacer algo diferente.

Esto dibuja si el mouse está presionado o no, así que no es lo que Pydude solicitó, sino casi.

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

Pruébalo en glslsandbox


0

Procesamiento, 93 bytes, 91 bytes si los espacios no cuentan

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

1
En PPCG, si no se menciona en el desafío, los espacios y todo cuentan como normales (como bytes en la codificación de elección, por defecto UTF-8). Por lo tanto, su puntaje sería de 92 bytes, ya que el primer espacio no se puede eliminar sin romper el programa, pero el segundo espacio se puede eliminar de forma segura.
dzaima

0

Logotipo de UCB con wxWidgets, 65 bytes

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

Explicación (el código asignado a la variable buttonactse ejecuta con cada clic del botón):

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

Al menos, creo que esto funciona. Debería de acuerdo con la documentación , pero aparentemente la buttonactvariable solo funciona en una compilación de wxWidgets y estoy luchando para construir UCBLogo con wxWidgets en un Linux moderno (¿waddyamean no puede lanzar un puntero hacia intatrás y hacia atrás?).

Logotipo de UCB sin wxWidgets, 73 bytes

Para ver el efecto deseado, puede ejecutar esta versión más larga con un bucle infinito.

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

Pero esto se bloquea ucblogoen mi máquina ... Parece una condición de carrera.

UCB logo, realmente trabajando en mi máquina, 80 bytes

setbg 7 setpc 0 ht pu
while[1=1][setpos mousepos if[button?][pd] fd 1 pu wait 1]
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.