AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / coding / Perguntas / 78127726
Accepted
hansoko
hansoko
Asked: 2024-03-08 20:40:07 +0800 CST2024-03-08 20:40:07 +0800 CST 2024-03-08 20:40:07 +0800 CST

Jogo Towers of Hanoi em javafx - nada é mostrado até que o jogo seja totalmente resolvido

  • 772

O método renderHanoi() deve mover os discos, limpando-os dos VBoxes e adicionando-os novamente na nova ordem após cada movimento ser feito, mas parece que nada é mostrado a menos que seja o último movimento, o que torna tudo bastante inútil .

Tentei diferentes métodos de criação de atrasos, como Thread.sleep, Platform.runLater, etc. Nenhum deles parece funcionar. Como faço para resolver isso?

import java.util.Arrays;
import java.util.Random;
import javafx.animation.AnimationTimer;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.scene.Scene;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;

public class App extends Application {

    @Override
    public void start(Stage stage) {
        HBox platform = new HBox();
        VBox[] towerBoxes = new VBox[] { new VBox(), new VBox(), new VBox()};
        platform.getChildren().addAll(Arrays.asList(towerBoxes));
        Hanoi testing = new Hanoi(10);
        testing.towerBoxes = towerBoxes;
        var scene = new Scene(platform, 640, 480);
        stage.setScene(scene);
        stage.show();
        testing.solve();
    }

    public static void main(String[] args) {
        launch();
    }
}

class Tower {
    private int sp = 0;
    private Rectangle[] disks;
    
    Tower(int n) {
        disks = new Rectangle[n];
    }
    
    public void push(Rectangle entry) {
        if (sp < disks.length)
            disks[sp++] = entry;
        else
            System.err.println(this + ".push(" + entry + ") failed, stack is full");
    }
    
    public Rectangle pop() {
        if (sp > 0)
            return disks[--sp];
        else {
            System.err.println(this + ".pop() failed, stack is empty");
            return null;
        }
    }
    
    public boolean hasEntry() {
        return sp > 0;
    }
    
    @Override
    public Tower clone() {
        Tower copy = new Tower(disks.length);
        copy.sp = this.sp;
        copy.disks = this.disks.clone();
        return copy;
    }
}

class Hanoi {
    Tower src;
    Tower aux;
    Tower dest;
    int n;
    
    public VBox[] towerBoxes;
    
    public Hanoi(int n) {
        src = new Tower(n);
        aux = new Tower(n);
        dest = new Tower(n);
        
        this.n = n;
        
        for (int i = 0; i < n; i++) {
            Rectangle disk = new Rectangle(30 + 20 * i, 10);
            Color diskColor = generateRandomColor();
            disk.setFill(diskColor);
            disk.setStroke(diskColor);
            src.push(disk);
        }
    }
    
    private static Color generateRandomColor() {
        Random random = new Random();
        double red = random.nextDouble();
        double green = random.nextDouble();
        double blue = random.nextDouble();
        
        return new Color(red, green, blue, 1.0);
    }
    
    private void solve(int n, Tower src, Tower aux, Tower dest) {
        if (n < 1) {
            return;
        }
        solve(n-1, src, dest, aux);
        dest.push(src.pop());
        System.out.println(n);
        solve(n-1, aux, src, dest);
    }
    
    public void solve() {
        renderHanoi();
        timer.start();
        solve(n, src, aux, dest);
    }
    
    AnimationTimer timer = new AnimationTimer() {
        @Override
        public void handle(long now) {
          renderHanoi(); // Update UI after each frame
        }
    };

    
    private void renderHanoi() {
        for (VBox towerBox:towerBoxes)
            towerBox.getChildren().clear();
        Tower[] towersCopy = new Tower[]{src.clone(), aux.clone(), dest.clone()};
        for (int i = 0; i < 3; i++)
            while (towersCopy[i].hasEntry())
                towerBoxes[i].getChildren().add(towersCopy[i].pop());
    }
}
java
  • 2 2 respostas
  • 56 Views

2 respostas

  • Voted
  1. Best Answer
    VGR
    2024-03-08T21:47:50+08:002024-03-08T21:47:50+08:00

    O problema é que seu método solve() retorna em uma pequena fração de segundo. Acontece tão rápido que não há nada para animar.

    Você estava no caminho certo. Queremos executar o solvemétodo em uma thread diferente, com chamadas para Thread.sleep, para que ele não seja executado muito rapidamente. Não podemos e não devemos chamar Thread.sleep no thread do aplicativo JavaFX (o thread que chama starttodos os manipuladores de eventos), porque isso atrasará todo o processamento de eventos, incluindo a pintura de janelas e o processamento de entradas de mouse e teclado.

    Então, primeiro, vamos adicionar Thread.sleep, algumas chamadas para Platform.runLater para atualizar a janela e um Thread para fazer tudo com segurança:

    private void solve(int n, Tower src, Tower aux, Tower dest)
    throws InterruptedException {
        assert !Platform.isFxApplicationThread() : "Wrong thread!";
    
        if (n < 1) {
            return;
        }
    
        solve(n-1, src, dest, aux);
        dest.push(src.pop());
        Platform.runLater(() -> renderHanoi());
        System.out.println(n);
        Thread.sleep(100);
    
        solve(n-1, aux, src, dest);
        Platform.runLater(() -> renderHanoi());
    }
    
    public void solve() {
        renderHanoi();
    
        Thread solveThread = new Thread(() -> {
            try {
                solve(n, src, aux, dest);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        solveThread.setDaemon(true);
        solveThread.start();
    }
    

    Ainda temos um problema: alterações em variáveis ​​​​ou campos feitas em um thread não têm garantia de serem vistas em outros threads. Esta seção da especificação da linguagem Java explica sucintamente:

    Por exemplo, no seguinte fragmento de código (quebrado), suponha que this.doneseja um volatilecampo não booleano:

    while (!this.done)
        Thread.sleep(1000);
    

    O compilador é livre para ler o campo this.doneapenas uma vez e reutilizar o valor armazenado em cache em cada execução do loop. Isso significaria que o loop nunca terminaria, mesmo se outro thread alterasse o valor de this.done.

    Java tem muitas maneiras de lidar com acesso multithread com segurança. Neste caso, basta utilizar synchronizedna classe Tower e finalna classe Hanói.

    Então, alteramos as declarações dos métodos de Tower para ficarem assim:

    public synchronized void push(Rectangle entry) {
    
    public synchronized Rectangle pop() {
    
    public synchronized boolean hasEntry() {
    
    @Override
    public synchronized Tower clone() {
    

    Isso garante que as alterações feitas nos campos de uma Torre no solvemétodo ficarão visíveis para o thread da aplicação JavaFX.

    A própria classe Hanoi também faz referência a src, aux e dest em diferentes threads. Poderíamos usar synchronizedaqui, mas é mais simples tornar esses campos finais:

    final Tower src;
    final Tower aux;
    final Tower dest;
    final int n;
    

    Java pode fazer muitas suposições seguras sobre finalcampos ao acessá-los a partir de vários threads, já que não há necessidade de se preocupar com a falha de vários threads em ver alterações nesses campos.

    • 6
  2. James_D
    2024-03-09T00:54:41+08:002024-03-09T00:54:41+08:00

    [TLDR: aqui está uma solução que não requer threading]

    Conforme apontado na excelente resposta do @VGR , o problema surge porque a solução do problema da torre acontece quase que instantaneamente. Portanto, assim que você tentar renderizá-lo, já estará resolvido. Se você tentar desacelerar colocando pausas entre cada movimento, será necessário executar o código de solução em um thread separado. A resposta mencionada acima mostra como fazer dessa maneira.

    Acredito firmemente em não usar vários threads quando não é necessário: o mais importante é que isso torna o código muito mais difícil de acertar e também (embora isso seja muito menos importante) porque consome recursos adicionais do sistema. A resposta do @VGR implementa isso corretamente com threading, mas saber que o código está correto quando você compartilha dados entre vários threads requer uma programação muito mais avançada do que soluções de thread único.

    Também acredito fortemente na separação dos dados em um aplicativo da apresentação (visualização) dos dados.

    Aqui está uma leve reformulação do seu código que separa os dados. Primeiro, a representação de uma torre, que é essencialmente uma lista de números inteiros que representam quais discos estão na torre. Há também um enum para determinar qual torre é:

    TowerID.java

    package org.jamesd.examples.hanoi.model;
    
    public enum TowerID {SRC, DEST, AUX}
    

    Torre.java

    package org.jamesd.examples.hanoi.model;
    
    import java.util.*;
    
    public class Tower {
    
        private final TowerID id;
        private final LinkedList<Integer> disks;
        private final List<Integer> publicDisks;
    
        Tower(TowerID id, Set<Integer> disks) {
            this.id = id;
            this.disks = new LinkedList<>(disks);
            this.disks.sort(Integer::compare);
            this.publicDisks = Collections.unmodifiableList(this.disks);
        }
    
        Tower(TowerID id) {
            this(id, Collections.emptySet());
        }
    
        public int pop() {
            return disks.pop();
        }
    
        public void push(int i) {
            disks.push(i);
        }
    
        public List<Integer> getDisks() {
            return publicDisks;
        }
    
        public TowerID getId() {
            return id;
        }
    }
    

    A representação do puzzle necessita apenas das três torres e de um meio de passar de uma para a outra. Acontece que será útil encapsular um movimento como um objeto separado (que é apenas um registro simples aqui):

    Mover.java

    package org.jamesd.examples.hanoi.model;
    
    public record Move(TowerID fromTower, TowerID toTower) {
        @Override
        public String toString() {
            return fromTower + " -> " + toTower;
        }
    }
    

    e então

    Hanói.java

    package org.jamesd.examples.hanoi.model;
    
    import java.util.stream.Collectors;
    import java.util.stream.IntStream;
    
    public class Hanoi {
    
        private final int n;
    
        private final Tower src ;
        private final Tower dest ;
        private final Tower aux;
    
        public Hanoi(int numDisks) {
            this.n = numDisks;
            src = new Tower(TowerID.SRC, IntStream.range(1, n+1).boxed().collect(Collectors.toSet()));
            dest = new Tower(TowerID.DEST);
            aux = new Tower(TowerID.AUX);
        }
    
        public void makeMove(Move move) {
            Tower fromTower = getTower(move.fromTower());
            Tower toTower = getTower(move.toTower());
            toTower.push(fromTower.pop());
        }
    
        public Tower getTower(TowerID id) {
            return switch(id) {
                case SRC -> src;
                case DEST -> dest;
                case AUX -> aux;
            };
        }
    
        public int getNumDisks() {
            return n;
        }
    }
    

    Observe que não há método aqui para resolver o quebra-cabeça. Resolver o quebra-cabeça significa apenas criar uma sequência de movimentos, dado o número de discos do quebra-cabeça. Aqui está o mesmo algoritmo do OP, fatorado em uma classe de solucionador separada:

    HanoiSolver.java

    package org.jamesd.examples.hanoi.model;
    
    import java.util.LinkedList;
    import java.util.List;
    
    public class HanoiSolver {
        private final int n ;
    
        public HanoiSolver(int nDisks) {
            this.n = nDisks;
        }
    
        public List<Move> solve() {
            List<Move> moves = new LinkedList<>();
            solve(moves, n, TowerID.SRC, TowerID.DEST, TowerID.AUX);
            return moves;
        }
    
        private void solve(List<Move> moves, int n, TowerID fromTower, TowerID destTower, TowerID auxTower) {
            if (n < 1) {
                return ;
            }
            solve(moves, n-1, fromTower, auxTower, destTower);
            moves.add(new Move(fromTower, destTower));
            solve(moves, n-1, auxTower, destTower, fromTower);
        }
    }
    

    Observe que agora podemos resolver um quebra-cabeça da torre de Hanói sem uma IU:

    package org.jamesd.examples.hanoi.model;
    
    public class Test {
        public static void main(String[] args) {
            HanoiSolver hanoi = new HanoiSolver(4);
            System.out.println(hanoi.solve());
        }
    }
    
    [SRC -> AUX, SRC -> DEST, AUX -> DEST, SRC -> AUX, DEST -> SRC, DEST -> AUX, SRC -> AUX, SRC -> DEST, AUX -> DEST, AUX -> SRC, DEST -> SRC, AUX -> DEST, SRC -> AUX, SRC -> DEST, AUX -> DEST]
    

    e a API que escrevemos também nos permite verificar o estado após cada movimentação em uma solução:

    package org.jamesd.examples.hanoi.model;
    
    import java.util.List;
    import java.util.stream.Stream;
    
    public class Test {
        public static void main(String[] args) {
            HanoiSolver hanoiSolver = new HanoiSolver(4);
            List<Move> moves = hanoiSolver.solve();
            Hanoi hanoi = new Hanoi(4);
            outputHanoi(hanoi);
            for (Move move : moves) {
                hanoi.makeMove(move);
                System.out.println(move);
                outputHanoi(hanoi);
            }
        }
    
        private static void outputHanoi(Hanoi hanoi) {
            Stream.of(TowerID.values())
                    .map(id -> id + " : " + hanoi.getTower(id).getDisks())
                    .forEach(System.out::println);
            System.out.println("-----------------");
        }
    }
    
    SRC : [1, 2, 3, 4]
    DEST : []
    AUX : []
    -----------------
    SRC -> AUX
    SRC : [2, 3, 4]
    DEST : []
    AUX : [1]
    -----------------
    SRC -> DEST
    SRC : [3, 4]
    DEST : [2]
    AUX : [1]
    -----------------
    AUX -> DEST
    SRC : [3, 4]
    DEST : [1, 2]
    AUX : []
    -----------------
    SRC -> AUX
    SRC : [4]
    DEST : [1, 2]
    AUX : [3]
    -----------------
    DEST -> SRC
    SRC : [1, 4]
    DEST : [2]
    AUX : [3]
    -----------------
    DEST -> AUX
    SRC : [1, 4]
    DEST : []
    AUX : [2, 3]
    -----------------
    SRC -> AUX
    SRC : [4]
    DEST : []
    AUX : [1, 2, 3]
    -----------------
    SRC -> DEST
    SRC : []
    DEST : [4]
    AUX : [1, 2, 3]
    -----------------
    AUX -> DEST
    SRC : []
    DEST : [1, 4]
    AUX : [2, 3]
    -----------------
    AUX -> SRC
    SRC : [2]
    DEST : [1, 4]
    AUX : [3]
    -----------------
    DEST -> SRC
    SRC : [1, 2]
    DEST : [4]
    AUX : [3]
    -----------------
    AUX -> DEST
    SRC : [1, 2]
    DEST : [3, 4]
    AUX : []
    -----------------
    SRC -> AUX
    SRC : [2]
    DEST : [3, 4]
    AUX : [1]
    -----------------
    SRC -> DEST
    SRC : []
    DEST : [2, 3, 4]
    AUX : [1]
    -----------------
    AUX -> DEST
    SRC : []
    DEST : [1, 2, 3, 4]
    AUX : []
    -----------------
    

    Para fazer uma UI para o quebra-cabeça, precisamos de algumas classes de UI para visualizar as torres:

    TorreView.java:

    package org.jamesd.examples.hanoi.ui;
    
    import javafx.scene.layout.Region;
    import javafx.scene.paint.Color;
    import javafx.scene.shape.Rectangle;
    import org.jamesd.examples.hanoi.model.Tower;
    
    import java.util.ArrayList;
    import java.util.List;
    
    public class TowerView extends Region {
    
        private final int totalNumDisks;
        private final Rectangle stem = new Rectangle();
        private final List<Integer> diskIndexes = new ArrayList<>();
        private final List<Rectangle> disks = new ArrayList<>();
    
        private static final double STEM_WIDTH = 10 ;
    
        public TowerView(int totalNumDisks) {
            this.totalNumDisks = totalNumDisks;
            stem.setFill(Color.SADDLEBROWN);
            getChildren().add(stem);
        }
    
        @Override
        protected void layoutChildren() {
            double leftEdge = snappedLeftInset();
            double availableWidth = getWidth() - leftEdge - snappedRightInset();
            double topEdge = snappedTopInset();
            double availableHeight = getHeight() - topEdge - snappedBottomInset();
            stem.setWidth(STEM_WIDTH);
            stem.setX(leftEdge + availableWidth / 2 - STEM_WIDTH / 2);
            stem.setY(topEdge);
            stem.setHeight(availableHeight);
    
            int nDisks = diskIndexes.size();
            for (int i = 0; i < nDisks; i++)  {
                int relWidth = diskIndexes.get(i);
                Rectangle disk = disks.get(i);
                double diskWidth = availableWidth * relWidth / totalNumDisks;
                disk.setWidth(diskWidth);
                disk.setHeight(availableHeight / totalNumDisks);
                disk.setX(leftEdge + availableWidth / 2 - diskWidth / 2);
                disk.setY(topEdge + availableHeight - (availableHeight * (nDisks - i)) / totalNumDisks);
            }
        }
    
        public void renderTower(Tower tower) {
            diskIndexes.clear();
            diskIndexes.addAll(tower.getDisks());
            getChildren().setAll(stem);
            disks.clear();
            for (Integer index : diskIndexes) {
                Rectangle disk = new Rectangle();
                disk.setFill(getColor(index));
                double arc = 25.0;
                disk.setArcWidth(arc);
                disk.setArcHeight(arc);
                disks.add(disk);
                getChildren().add(disk);
            }
        }
    
        private Color getColor(int index) {
            return Color.gray(1.0 - 1.0 * index / totalNumDisks);
        }
    }
    
    

    e para tudo:

    HanóiView.java:

    package org.jamesd.examples.hanoi.ui;
    
    import javafx.scene.layout.Background;
    import javafx.scene.layout.HBox;
    import javafx.scene.layout.Priority;
    import javafx.scene.paint.Color;
    import org.jamesd.examples.hanoi.model.Hanoi;
    import org.jamesd.examples.hanoi.model.TowerID;
    
    public class HanoiView extends HBox {
    
        public HanoiView() {
            setSpacing(10);
            setFillHeight(true);
            setBackground(Background.fill(Color.SKYBLUE));
        }
    
        public void renderHanoi(Hanoi hanoi) {
            int n = hanoi.getNumDisks();
            TowerView src = createTowerView(n);
            TowerView dest = createTowerView(n);
            TowerView aux = createTowerView(n);
            src.renderTower(hanoi.getTower(TowerID.SRC));
            dest.renderTower(hanoi.getTower(TowerID.DEST));
            aux.renderTower(hanoi.getTower(TowerID.AUX));
            getChildren().setAll(src, dest, aux);
        }
    
        private TowerView createTowerView(int ndisks) {
            TowerView view = new TowerView(ndisks);
            setHgrow(view, Priority.ALWAYS);
            return view;
        }
    }
    

    To visualize a solution in an animation, we can get a list of the moves from the solver, create a timeline with a keyframe for each move, and in each keyframe update the model with each move and rerender the view:

                HanoiSolver solver = new HanoiSolver(hanoi.getNumDisks());
                List<Move> moves = solver.solve();
                Duration frameTime = Duration.seconds(0.5);
                Duration current = Duration.ZERO;
                Timeline timeline = new Timeline();
                for (Move move : moves) {
                    current = current.add(frameTime);
                    KeyFrame keyFrame = new KeyFrame(current, evt -> {
                        hanoi.makeMove(move);
                        hanoiview.renderHanoi(hanoi);
                    });
                    timeline.getKeyFrames().add(keyFrame);
                }
                timeline.play();
    

    Here is this animation assembled into an application, with a few controls added:

    package org.jamesd.examples.hanoi.ui;
    
    import javafx.animation.KeyFrame;
    import javafx.animation.Timeline;
    import javafx.application.Application;
    import javafx.scene.Scene;
    import javafx.scene.control.Button;
    import javafx.scene.control.Label;
    import javafx.scene.control.Spinner;
    import javafx.scene.layout.BorderPane;
    import javafx.scene.layout.HBox;
    import javafx.stage.Stage;
    import javafx.util.Duration;
    import org.jamesd.examples.hanoi.model.Hanoi;
    import org.jamesd.examples.hanoi.model.HanoiSolver;
    import org.jamesd.examples.hanoi.model.Move;
    
    import java.util.List;
    
    public class App extends Application {
    
        private Hanoi hanoi ;
    
        @Override
        public void start(Stage stage) throws Exception {
            HBox controls = new HBox(5);
            controls.getChildren().add(new Label("Number of disks:"));
            Spinner<Integer> numDisksSpinner = new Spinner<>(2, 15, 5);
            Button solve = new Button("Solve");
            controls.getChildren().addAll(numDisksSpinner, solve);
    
            HanoiView hanoiview = new HanoiView();
            hanoi = new Hanoi(numDisksSpinner.getValue());
            hanoiview.renderHanoi(hanoi);
    
            numDisksSpinner.valueProperty().addListener((obs, oldValue, newValue) -> {
                hanoi = new Hanoi(newValue);
                hanoiview.renderHanoi(hanoi);
            });
    
            solve.setOnAction(e -> {
                controls.setDisable(true);
                hanoi = new Hanoi(numDisksSpinner.getValue());
                hanoiview.renderHanoi(hanoi);
                HanoiSolver solver = new HanoiSolver(hanoi.getNumDisks());
                List<Move> moves = solver.solve();
                Duration frameTime = Duration.seconds(0.5);
                Duration current = Duration.ZERO;
                Timeline timeline = new Timeline();
                for (Move move : moves) {
                    current = current.add(frameTime);
                    KeyFrame keyFrame = new KeyFrame(current, evt -> {
                        hanoi.makeMove(move);
                        hanoiview.renderHanoi(hanoi);
                    });
                    timeline.getKeyFrames().add(keyFrame);
                }
                timeline.setOnFinished(evt -> controls.setDisable(false));
                timeline.play();
            });
    
            BorderPane root = new BorderPane();
            root.setTop(controls);
            root.setCenter(hanoiview);
            Scene scene = new Scene(root, 800, 500);
            stage.setScene(scene);
            stage.show();
        }
    
        public static void main(String[] args) {
            Application.launch(args);
        }
    }
    

    Note we don't use any built-in observability here. We could create the Tower implementation with an ObservableList for the disks and have the view class observe the list, in order to avoid re-rendering the views "by hand" in each frame.

    • 4

relate perguntas

  • Lock Condition.notify está lançando java.lang.IllegalMonitorStateException

  • Resposta de microsserviço Muitos para Um não aparece no carteiro

  • Validação personalizada do SpringBoot Bean

  • Os soquetes Java são FIFO?

  • Por que não é possível / desencorajado definir um lado do servidor de tempo limite de solicitação?

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Vue 3: Erro na criação "Identificador esperado, mas encontrado 'import'" [duplicado]

    • 1 respostas
  • Marko Smith

    Por que esse código Java simples e pequeno roda 30x mais rápido em todas as JVMs Graal, mas não em nenhuma JVM Oracle?

    • 1 respostas
  • Marko Smith

    Qual é o propósito de `enum class` com um tipo subjacente especificado, mas sem enumeradores?

    • 1 respostas
  • Marko Smith

    Como faço para corrigir um erro MODULE_NOT_FOUND para um módulo que não importei manualmente?

    • 6 respostas
  • Marko Smith

    `(expression, lvalue) = rvalue` é uma atribuição válida em C ou C++? Por que alguns compiladores aceitam/rejeitam isso?

    • 3 respostas
  • Marko Smith

    Quando devo usar um std::inplace_vector em vez de um std::vector?

    • 3 respostas
  • Marko Smith

    Um programa vazio que não faz nada em C++ precisa de um heap de 204 KB, mas não em C

    • 1 respostas
  • Marko Smith

    PowerBI atualmente quebrado com BigQuery: problema de driver Simba com atualização do Windows

    • 2 respostas
  • Marko Smith

    AdMob: MobileAds.initialize() - "java.lang.Integer não pode ser convertido em java.lang.String" para alguns dispositivos

    • 1 respostas
  • Marko Smith

    Estou tentando fazer o jogo pacman usando apenas o módulo Turtle Random e Math

    • 1 respostas
  • Martin Hope
    Aleksandr Dubinsky Por que a correspondência de padrões com o switch no InetAddress falha com 'não cobre todos os valores de entrada possíveis'? 2024-12-23 06:56:21 +0800 CST
  • Martin Hope
    Phillip Borge Por que esse código Java simples e pequeno roda 30x mais rápido em todas as JVMs Graal, mas não em nenhuma JVM Oracle? 2024-12-12 20:46:46 +0800 CST
  • Martin Hope
    Oodini Qual é o propósito de `enum class` com um tipo subjacente especificado, mas sem enumeradores? 2024-12-12 06:27:11 +0800 CST
  • Martin Hope
    sleeptightAnsiC `(expression, lvalue) = rvalue` é uma atribuição válida em C ou C++? Por que alguns compiladores aceitam/rejeitam isso? 2024-11-09 07:18:53 +0800 CST
  • Martin Hope
    The Mad Gamer Quando devo usar um std::inplace_vector em vez de um std::vector? 2024-10-29 23:01:00 +0800 CST
  • Martin Hope
    Chad Feller O ponto e vírgula agora é opcional em condicionais bash com [[ .. ]] na versão 5.2? 2024-10-21 05:50:33 +0800 CST
  • Martin Hope
    Wrench Por que um traço duplo (--) faz com que esta cláusula MariaDB seja avaliada como verdadeira? 2024-05-05 13:37:20 +0800 CST
  • Martin Hope
    Waket Zheng Por que `dict(id=1, **{'id': 2})` às vezes gera `KeyError: 'id'` em vez de um TypeError? 2024-05-04 14:19:19 +0800 CST
  • Martin Hope
    user924 AdMob: MobileAds.initialize() - "java.lang.Integer não pode ser convertido em java.lang.String" para alguns dispositivos 2024-03-20 03:12:31 +0800 CST
  • Martin Hope
    MarkB Por que o GCC gera código que executa condicionalmente uma implementação SIMD? 2024-02-17 06:17:14 +0800 CST

Hot tag

python javascript c++ c# java typescript sql reactjs html

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve