Borsa KoTH


23

Borsa tamamen bilginin hızı ile ilgili. Önceki zorluklardan farklı olarak , mevcut hisse senedi fiyatı rastgele değildir: oyunu oynayanlar tarafından belirlenir. Düşük fiyatlı bir stoğu herhangi birinden önce tanımlayabilirseniz, kendinize bir para kazanma programı yazdınız.

Fiyat ne kadar insan için hisse senedi alım satım yapar, Değer ise oyunun sonunda hisse senedi miktarını ifade eder.

Her oyuncu, her hisse senedi için 1000 ve 0 göreceli net değer ile başlar. Her hisse senedi gizli bir değere sahiptir ve oyunun sonunda puanınız(stockValue for each ownedStock) + netWorth . Net değeriniz negatif olabilir. N oyunculu bir oyunda, N hisse var.

Adımlar:

Oyun aşağıdaki adımları takip eder:

  1. Tek bir hisse senedinin gizli değeri verilir.
  2. X of Y hisse senedini $ Z karşılığında satmayı teklif ettin
  3. Tüm oyunculara teklif verilir ve her biri kabul etmek için birini seçebilir
  4. Tüm oyuncular kabul edilen tekliflerden haberdar edilir
  5. 2. adıma geri dönün

Her bir adım aşağıda ayrıntılı olarak verilmiştir:

  1. void secretValue(int stockType, int value):

    • Öğrendiğiniz değer başka hiçbir oyuncuya açıklanmaz.
    • Değer 0ve arasında1000
    • Düşük değerler, yüksek değerlerden daha fazla meydana gelmeye benzer (kare dağılım)
  2. Offer makeOffer(List<Stock> currentStock)

    • nullTeklif vermemek için geri dönebilirsiniz .
  3. Offer acceptOffer(List<Offer> offers)

    • nullHiçbirini kabul etmek için geri dönebilirsiniz .
    • Kullanılabilir teklif yoksa, bu numara aranmaz
    • Kabul ederseniz, net değeriniz $ Z ile düşer (negatif olabilir) ve X hissesinin X değerini alır. Tersi satıcıda gerçekleşir.
    • Bir teklifi kabul ederseniz, değişim hemen gerçekleşecek ve teklifler kaldırılacak, böylece ek oyuncular kabul edemez.
  4. void acceptedOffers(List<Offer> offers)

    • Kabul edilen tekliflerinizi de içerir

Statik değişkenlere veya dosyalara yazma izin verilmez. (Oyundan oyuna kalıcı veri yok) Ciddi olmayan yarışmacılara izin verilir.

Arabirimler:

public final class Stock {
    public Stock(int stockType, int amount);
    public int getType();
    public int getAmount();
    public Stock minus(Stock other);
    public Stock plus(Stock other);
    public Stock minus(int amount);
    public Stock plus(int amount);
    public Stock setAmount(int amount);
}
public class Offer {
    public Offer(Stock offer, int payment);
    public Stock getOffer();
    public int getPayment();
}

Java dışı gönderimler:

  • Tüm çağrılar iki hat oluşmaktadır: İlk satır çağrılan fonksiyonudur: SecretValue, MakeOffer, AcceptOffer, AcceptedOffers, SetRandom, ve gerçek veri içeren ikinci hat.
  • Stoklar bir ile biçimlendirilir :sınırlayıcı: stockType:stockAmount.
  • Teklifler bir @sınırlayıcıyla biçimlendirilir :offer@price
  • Listeler ;sınırlayıcı ile biçimlendirilmiş
  • SecretValue:sınırlayıcı ile biçimlendirilmiş :stockType:value
  • RandomSeedGönderiminizi deterministik yapmak için kullanılır. Gönderiminiz rastgelelik kullanıyorsa, lütfen tohum olarak geçen tamsayı değerini kullanın!
  • Tüm işlev çağrıları gerek bir yanıt. Yanıt nullveya ise void, boş bir dize döndürün.
  • Lütfen command.txtgönderinizi çalıştırmak için komut satırı argümanlarını veren bir tane ekleyin.

puanlama

1000 turdan oluşan oyunlar birçok kez oynanacak. Oyuncular ELO sistemine göre puanlanacak ve benzer beceri seviyelerinde oyuncularla eşleştirilecektir. En yüksek final ELO puanı olan oyuncu kazanır! (Sistemi değiştirdim, böylece her oyun, ELO puanları her oyuncu eşleşmesi için güncellenir)

Bir başlık ile Gönderiminizi başlayın böylece kontrolör, bir autodownloader içerir: Name, Language. Gönderiminiz Java değilse, her kod bloğu dosyanın adıyla başlamalıdır. (yazınızdaki ilk satır olması gereken komut dosyası hariç)

Koşu

Bu projeyi yürütmenin 2 yolu vardır:

  1. Kaynak kodu indirin, derleyin ve çalıştırın. Kaynağı Github'da bulabilirsiniz . Koşmakgit clone --recursive https://github.com/nathanmerrill/StockExchange.git

  2. JAR çalıştırılabilir dosyasını indirin. Gönderimler mevcut çalışma dizininizdeki /submissionsklasöre yerleştirilmelidir. Sadece JAR , sadece gönderileri veya her ikisini de indirebilirsiniz.

Aktarın runprojeyi (varsayılan seçenek) çalıştırın veya geçmek downloadşimdiye kadar bu sorunun tüm gönderimleri indirmek için.

sayı tahtası

1.  1308.1220497323848  Cheater
2.  1242.0333695640356  InsideTrader
3.  1158.3662658295411  UncleScrooge
4.  1113.8344000358493  BlackMarket
5.  1051.8370015258993  DartMonkey
6.  983.0545446731494   WarGamer
7.  939.457423938002    Spammer
8.  901.4372529538886   DumbBot
9.  859.0519326039137   ShutUpAndTakeMyMoney
10. 852.9448222849587   VincentKasuga
11. 718.2112067329083   Profiteer

hisse senedi mülkleri halka açık değil, getter yöntemlerini kullanmasını
isteyin

@AgentCrazyPython daha iyi?
Nathan Merrill,

Mevcut fiyatlar önceki fiyatlarla korele mi?
noɥʇʎԀʎzɐɹƆ

1
Bir sohbet odası memnuniyetle karşılanacaktır.
TheNumberOne,

Yanıtlar:


13

Dolandırıcı, Java

Para için hiçbir şey satmaya çalışır.

import java.util.List;
import java.util.Random;
import com.ppcg.stockexchange.*;

public class Cheater extends Player {
    private Random random = new Random();

    public Offer acceptOffer(List<Offer> offers) {
        return null;
    }

    public Offer makeOffer(List<Stock> currentStock){
        Stock stock = randomStock();
        int price = random.nextInt(100) + 1;
        return new Offer(stock.setAmount(0), price);
    }
}

5
İşte bu büyük depresyon böyle oluyor! Bunun ucuz olan birçok botu kırdığını görebiliyordum ...
Socratic Phoenix

Tebrikler! Kritik bir hatayı düzelttim ve şimdi bu bot ilk sırada!
Nathan Merrill

Vay, diğer botlar o zaman yeterince iyi değil, bu aptal bot kazanabilir ki
justhalf

8

WarGamer, Java

Kuralların eksiksiz bir incelemesi üzerine, birincil kazanma hareketinin oynamak değil olduğuna karar verdim. Stok satmayı teklif eden herkes muhtemelen fiyatı bilir ve satıştan kazanç sağlar. Geçiş yapılabildiği için Integer.MAX_VALUE dolara sesini kesecek ve paramı ısırmayı umarak "şaka" teklifi verecek.

import java.util.List;
import com.ppcg.stockexchange.*;
import com.ppcg.kothcomm.game.AbstractPlayer;
import com.ppcg.kothcomm.utils.Tools;

import java.util.List;

public class WarGamer extends Player {
static final boolean FRAUD = false;
    /**
     * @param offers All available offers
     * @return An offer you want to accept, or null if you want to accept neither.
     */
    public Offer acceptOffer(List<Offer> offers){
        return null;
    }

    public Offer makeOffer(List<Stock> currentStock){
    if(FRAUD)
    return new Offer(new Stock(0,1),Integer.MAX_VALUE);
        //defraud shut up and take my money            
    return null;
    }
}

1
Bu muhtemelen işe yarayacaktı, ancak yollarını biraz daha yükseğe saran girişler olacağını umuyorum. Genellikle vardır.
Geobits

Bu derleme değil.
Rainbolt,

@Rainbolt bağımlılıklarına sahiptir. Var olduğundan emin olmalısın.
Rohan Jhunjhunwala

@Rainbolt ne derleyici hatası alıyorsunuz
Rohan Jhunjhunwala


5

KapatmaAndTakeMyMoney, Java

import java.util.List;
import com.ppcg.stockexchange.*;

public class ShutUpAndTakeMyMoney extends Player {
    public ShutUpAndTakeMyMoney() {}

    public Offer acceptOffer(List<Offer> offers) {
        try {
            return offers.get(0);
        } catch (Exception ex) {
            return null;
        }
    }
    public Offer makeOffer(List<Stock> stock) {
        return null;
    }
}

Herhangi bir teklifi kabul eder.


Aslında botun için teşekkür ederim
Rohan Jhunjhunwala

6
beni zengin etmek için +
1'leri var

1
Bana göre bu, her cevabın " kullanılan kazanan kriterler için ciddi bir rakip olması " şartı ile gerçekten uyumlu değil gibi görünüyor .
Peter Taylor

2
@PeterTaylor Ciddi, lider
panosunda

Bu, tartışmalı bir intihar girişiydi , çünkü diğer botların değerlerinden daha fazla miktarda hisse satmasını beklemek makul bir bedel karşılığında hisse senedi satın almanıza yol açıyor.
Mego

4

DumbBot, Java

Kendinizinkini oluştururken bu botu kullanın. Gizli stokunu indirimli bir fiyatla sunar.

import java.util.List;
import com.ppcg.stockexchange.*;
public class DumbBot extends Player {
    public Offer acceptOffer(List<Offer> offers) {
        return null;
    }
    public Offer makeOffer(List<Stock> currentStock){
        return new Offer(currentStock.get(secretStockType).setAmount(1), Math.max(1, secretStockValue - 5));
    }
    public void secretValue(int stockType, int value) {
        super.secretValue(stockType, value);
    }
    public void acceptedOffers(List<Offer> acceptedOffers) {
    }
}

1
Paramı idare etmesini istiyor gibiyim
Rohan Jhunjhunwala

Lütfen bu topluluğu wiki yap
noɥʇʎԀʎzɐɹƆ

@AgentCrazyPython neden?
Nathan Merrill,

@NathanMerrill, bu aptal botun karşılığını verdi
noɥʇʎԀʎzɐɹƆ 23

@AgentCrazyPython İnsanların bu düzenlemeyi yapmasını istemiyorum ... Temsilcileri gerçekten umursamıyorum, bu yüzden fazla oy kullanmamayı (ya da düşük oy kullanmamayı) çekinmeyin
Nathan Merrill

3

python_starter, Python 3

Bunu herhangi bir python (veya diğer dil) programları için başlangıç ​​noktası olarak kullanın.

Rastgele bir teklifi kabul eder.

Komut dosyası:

python3 starter.py

Programı:

starter.py
import random
from functools import total_ordering


LIST_DELIMITER = ';'
STOCK_DELIMITER = ':'
OFFER_DELIMITER = '@'


@total_ordering
class Stock:
    @staticmethod
    def parse(string: str):
        return Stock(*map(int, string.split(STOCK_DELIMITER)))

    def __init__(self, stock_type: int, amount: int):
        self.type = stock_type
        self.amount = max(amount, 0)

    def __str__(self):
        return str(self.type)+STOCK_DELIMITER+str(self.amount)

    def __eq__(self, other):
        return self.amount == other.type

    def __lt__(self, other):
        return self.amount < other.amount

    def update(self, amount) -> 'Stock':
        return Stock(self.type, amount)

    def __mul__(self, other: int) -> 'Stock':
        return self.update(self.amount*other)

    def __floordiv__(self, other: int) -> 'Stock':
        return self.update(self.amount//other)

    def __add__(self, other: int) -> 'Stock':
        return self.update(self.amount+other)

    def __sub__(self, other: int) -> 'Stock':
        return self.update(self.amount-other)


class Offer:
    @staticmethod
    def parse(string: str) -> 'Offer':
        try:
            offer, payment = string.split(OFFER_DELIMITER)
        except ValueError:
            raise Exception("Cannot unpack "+string)
        return Offer(Stock.parse(offer), int(payment.strip()))

    def __init__(self, offer: Stock, payment: int):
        self.offer = offer
        self.payment = payment

    def __str__(self):
        return str(self.offer)+OFFER_DELIMITER+str(self.payment)


def read_stock_value(value: str):
    global hidden_price, hidden_stock
    stock, price = value.split(STOCK_DELIMITER)
    hidden_price = float(price)
    hidden_stock = int(stock)


def process_input():
    handlers = {
        "SecretValue": read_stock_value,
        "RandomSeed": read_seed,
        "MakeOffer": make_offer,
        "AcceptOffer": accept_offer,
        "AcceptedOffers": accepted_offers,
    }
    method = input().strip()
    data = input().strip()
    output = handlers[method](data)
    if output is not None:
        print(str(output))
    else:
        print()


def read_seed(seed: str):
    random.seed(int(seed))


def start():
    while True:
        process_input()


hidden_stock = None
hidden_price = None


def make_offer(current_stock: str):
    current_stock = map(Stock.parse, current_stock.split(LIST_DELIMITER))
    pass


def accept_offer(available_offers: str):
    available_offers = list(map(Offer.parse, available_offers.split(LIST_DELIMITER)))
    return random.sample(available_offers, 1)[0]


def accepted_offers(offers: str):
    offers = map(Offer.parse, offers.split(LIST_DELIMITER))
    pass


if __name__ == "__main__":
    start()

1
bu çok karmaşık.
noɥʇʎԀʎzɐɹƆ

2
Çoğu yardımcı şeylerdir. Python ile yazıyorsanız, alt 3 işlevini uygulamanız yeterlidir.
Nathan Merrill,

bu ne işe yarıyor?
noɥʇʎԀʎzɐɹƆ

Bot rastgele bir hisse senedi kabul ediyor. Yardımcı malzeme ayrıştırma / kodlamanın yanı sıra Teklif / Stok için sınıflar sağlar.
Nathan Merrill,

... ve kazanıyor: /
noɥʇʎԀʎzɐɹƆ

3

VincentKasuga, Java

Java'mın geçerli olup olmadığından emin değilim. Gözden geçirin.

Nasıl çalışır

- tüm hisse senetlerine sahipseniz, hisse senedinin fiyatını belirleyebilirsiniz. Tek satıcı sensin. 1. Tüm stokları satın alın. 2. Tüm stokların fiyatını son onaylamadan süper yüksek olacak şekilde ayarlayın. 3. KAR! - Bu normalde mümkün değil çünkü ...

  • Fiyat genellikle sonsuzluğa fırlardı ... ama bir sınırı var!
  • ... (gelmesi için daha fazla sebep)

Nasıl çalışır, v2

  • Fiyat yapay olarak bir miktar anarşist devlet tarafından belirlenir.
  • Bu ekonomik olarak kötü
  • Bot tahmin etmiyor - pazar yapısındaki doğal bir kusurdan faydalanıyor!

Yapmak

  • Piyasayı birçok kez köşeye sıkıştır! Muahaha!

SSS

S: Vincent Kasuga kim?

C: ABD'deki bütün soğan ve soğan vadeli işlemlerini aldı. (hepsini gizli bir depoya koyun) Endüstriyi fidye altında tuttum - bana X milyon ver yoksa fiyatı gökyüzüne indiririm ve hepiniz iflas edersiniz.

Ama orada durmadı.

Sonra, gizlice soğan ETF'sini kısalttı (düşeceğine bahse girer). Tüm soğanları tek seferde sattı, fiziksel olarak binlerce kamyona borsaya teslim etti. Soğan torbası soğandan daha ucuzdur. O milyonlarca AGİT yaptı. Kısacası, Hudson nehri soğanla dolup taşıyordu.

O gerçek bir insan.

Kod

import com.ppcg.stockexchange.Offer;
import com.ppcg.stockexchange.Player;
import com.ppcg.stockexchange.Stock;

import java.util.List;

public class VincentKasuga extends Player {
    private int knownStock;
    private int knownPrice;
    private int corneredStockType = -1;
    private int corneredLikelehood = 0;
    private boolean marketCornered;
    private int ticks;

    public Offer acceptOffer(List<Offer> offers) {
        if (!marketCornered) {
            Offer maxOffer = null;
            int maxAmount = 0;
            if (corneredStockType == -1) {
                for (Offer offer: offers) {
                    if (offer.getOffer().getAmount() > maxAmount) {
                        maxAmount = offer.getOffer().getAmount();
                        maxOffer = offer;
                    }
                }
            } else {
                for (Offer offer: offers) {
                    if (offer.getOffer().getAmount() > maxAmount && offer.getOffer().getType() == corneredStockType) {
                        maxAmount = offer.getOffer().getAmount();
                        maxOffer = offer;
                    }
                }
            }


            if (maxOffer == null) {
                // may have cornered the market
                corneredLikelehood++;
                if (corneredLikelehood == 5) {
                    // probably cornered the market
                    marketCornered = true;
                }
            }
            return maxOffer;
        } else {
            // who needs offers when the market is cornered!?
            return null;
        }
    }

    public Offer makeOffer(List<Stock> currentStock) {
        ticks++;
        if (ticks >= 999) {
            // SELL SELL SELL!
            return new Offer(new Stock(corneredStockType, 1000), 1000);
        } else {
            return null;
        }
    }

    public void secretValue(int stockType, int value) {
        knownStock = stockType;
        knownPrice = value;
        if (stockType == corneredStockType) {
            if (knownPrice == 1000) {
                corneredLikelehood += 3;
            } else if (knownPrice < 900){
                // didn't corner the market.
                corneredLikelehood = 0;
            }
        }
    }
}

“Altın Piyasasını köşeye sıkıştırdım, Bay Bond!”


Botlar için bir otomatik indirici ekledim. Lütfen kodunuzu bir kod bloğuna yerleştirin. Sığmayacaksa sorun değil.
Nathan Merrill,

@NathanMerrill anlıyorum. Ancak derler mi?
noɥʇʎԀʎzɐɹƆ

@NathanMerrill yapıldı. Probs derlenmiyor. ilginç strateji, ha? Ve ekonomi alanında bir ders!
noɥʇʎԀʎzɐɹƆ

for (offer: offers)->for (Offer offer: offers)
Nathan Merrill,

corneredStockType == nullayrıca geçerli değil. bir intolamaz null.
MegaTom

2

Spammer, Java

import java.util.List;
import java.util.ArrayList;
import com.ppcg.stockexchange.*;

public class Spammer extends Player {
    private boolean panic = false;

    public Offer acceptOffer(List<Offer> offers) {
        for (Offer offer : offers) {
            if (this.panic || offer.getPayment() < 20)
                return offer;
        }
        return null;
    }
    public Offer makeOffer(List<Stock> currentStock) {
        if (currentStock.size() > 1) { // Don't sell all the stock
            this.panic = false;
            return new Offer(currentStock.get(secretStockType).setAmount(1), 1);
        }
        this.panic = true; // BUY
        return null;
    }
}

Piyasayı gerçekten ucuz bir hisse senedi ile değiştirin ve yalnızca fiyatı 20'nin altında olduğunda hisse senedi satın alın.


Büyük Buhran içinde iyi çalışıyor
noɥʇʎԀʎzɐɹƆ

... bu nasıl kazanıyor?
noɥʇʎԀʎzɐɹƆ

2

DartMonkey, Java

(rekabet etmeyen: Kazanmayacak ve zaten başka bir cevabım var)

Dart maymunu bir şeyler atmayı seviyor ... ve yanında büyük bir sivri çubuk var. Duvarda biraz kağıt görüyor. Bam! Bam! Bam! Hiç bir zaman, Dart Monkey 80 dart atıldı! Dartların yarısı kırmızı, diğer yarısı mavi ve üzerinde rasgele sayılar var! Dart maymunu bir bilgisayar görür ... dart maymunu türleri. Dart maymunu sayıları sever. Dart maymunu dartlarından biraz para kazanıyor ...


Tüm ciddiyetle, DartMonkey, stok sayısının iki katı olan bir tam sayı dizisi başlatır. Almak / satmak istediği hisse senedi için bir, hisse senedi fiyatı için bir numara saklar. Daha sonra diziden satış stoklarını değiştirir ve diziye göre teklifleri kabul eder. Diziden hiçbir hisse senedi yoksa, hiçbir şey teklif etmez ve diziden kendisine hiçbir teklif vermezse, hiçbir şey kabul etmez.


Bu cevap, sohbette dart maymunlarından bahseden @TheNumberOne'dan ilham aldı.

import com.ppcg.stockexchange.Offer;
import com.ppcg.stockexchange.Player;
import com.ppcg.stockexchange.Stock;

import java.util.List;
import java.util.Random;

public class DartMonkey extends Player {
    private int basePrice = 100;
    private int numStocks;
    private int[] dartBoard;
    private boolean first = true;

    @Override
    public Offer acceptOffer(List<Offer> offers) {
        for(Offer offer : offers) {
            Stock stock = offer.getOffer();
            int type = stock.getType();
            int amount = stock.getAmount();
            int price = offer.getPayment();
            if(this.dartBoard[type] < 0 && amount <= -this.dartBoard[type] && price <= this.dartBoard[type + this.numStocks]) {
                this.dartBoard[type] = 0;
                return offer;
            }
        }
        return null;
    }

    @Override
    public Offer makeOffer(List<Stock> stocks) {
        if(this.first) {
            this.first = false;
            this.numStocks = stocks.size();
            this.dartBoard = new int[this.numStocks * 2];
            Random random = this.getRandom();
            for (int i = 0; i < 20; i++) {
                int index = random.nextInt(this.dartBoard.length / 2);
                this.dartBoard[index] = random.nextInt(1001);
                this.dartBoard[this.numStocks + index] = random.nextInt(1001);
            }

            for (int i = 0; i < 20; i++) {
                int index = random.nextInt(this.dartBoard.length / 2);
                this.dartBoard[index] = -random.nextInt(1001);
                this.dartBoard[this.numStocks + index] = random.nextInt(1001);                
            }
        }

        for (Stock stock : stocks) {
            int type = stock.getType();
            if(this.dartBoard[type] > 0) {
                Offer offer = new Offer(stock.setAmount(this.dartBoard[type]), this.basePrice + this.dartBoard[type + this.numStocks]);
                this.dartBoard[type] = 0;
                this.dartBoard[type + this.numStocks] = 0;
                return offer;
            }
        }

        return null;
    }

}

Görüyorum ki duvardan aşağıya rastgele bir yürüyüşe çıkmışsınız?
Rohan Jhunjhunwala,

Bu, tartışmasız izin verilen bir intihar girişiydi .
Mego

1
@Mego Nasıl olduğunu bilmiyorum ... Bir intihar girişinin 0 dolara hisse satması bekleniyor, bu giriş ne aldığını ve rastgele sattığını belirler. Bu kesinlikle kurallara aykırı değildir ....
Socratic Phoenix

2

InsideTrader, Java

InsideTrader etrafa baktı ve herkesin yaratıcı olmaya çalıştığını gördü. Ama yaratıcı bir şey yaptı: beklenenleri yapın.

Bu bot "değer" olduğunda satın alır çünkü "yatırım kararlarını" "yönlendirmek" için "bazı" dahili belgeleri "ödünç alır.

Yapılacaklar ve kodda nasıl çalıştığı. ;)

"Kod"

import java.util.List;

import com.ppcg.stockexchange.*;

public class InsideTrader extends Player {
    public String coverStory = "I can tell the good companies from the bad ones.";
    private String theTruth = "I'm cheating. (but so is everyone else)";
    private String ambitions = "Learn to \"follow the market\"";  // don't steal this idea
    private int secretStock = -1;
    private int secretStockValue = -1;

    private int appraiseOffer(Offer offer) {
        /* get how much the offer is worth, 0 if it's not the secret stock */
        if (offer.getOffer().getType() != secretStock ||offer.getOffer().getAmount() == 0) {
            return 0;
        }
        return (offer.getPayment()/offer.getOffer().getAmount())  // price per stock...
                - secretStockValue  // minus value of stock.
                ;
    }
    public Offer acceptOffer(List<Offer> offers) {
        Offer bestOffer = null;
        int bestOfferValue = -1;
        for (Offer offer :
                offers) {
            int value = appraiseOffer(offer);
            if (value > bestOfferValue && value > 0) {
                bestOfferValue = value;
                bestOffer = offer;
            }
        }
        return bestOffer;
    }

    public Offer makeOffer(List<Stock> currentStock) {
        return new Offer(new Stock(0,1), Integer.MAX_VALUE);
    }

    public void secretValue(int stockType, int value) {
        secretStock = stockType;
        secretStockValue = value;
    }

    public void acceptedOffers(List<Offer> acceptedOffers) {

    }
}

Dosyanın başında bu ekstra sınıflara sahip olamazsınız ... sözdizimsel olarak geçersizdir ... herkese açık olmadan sonuna eklenebilirler, sanırım
Socratic Phoenix

Error on line 50: modifier private not allowed here Error on line 54: modifier private not allowed here. Sadece sınıfları kaldırırdım ve genişletmesini isterdimPlayer
Nathan Merrill

Sadece bir not, bazı yeni botlar sıfır miktarda hisse senedi sunuyor, bu yüzden botunuz appraiseOffer'ın geri dönüşünden bir ArithimeticException (/ sıfıra) atıyor ... belki bir çek veya başka bir şey ekleyebilir miyim?
Sokratic Phoenix,

@SocraticPhoenix Teşekkürler, çözecek.
noɥʇʎԀʎzɐɹƆ

Tebrikler, bu bot şu anda ikinci!
Nathan Merrill

2

WallStreet, Kotlin

Yüksek satış yaparak ve düşük satın alarak başlar ve kademeli olarak fiyatın gerçekte düşündüğü şeye kayar. Ayrıca, bunu kotlin'de kendiniz yapmak için bir şablon olarak kullanabilirsiniz.

Not: Burada, güvenilir bir şekilde üreyemediğim için bir hata var. Programım çökerse veya sorun yaşarsa , lütfen sohbete katılın ve içeriğin bir pastırmasını bağlayınsubmissions/other/WallStreet/log.txt

kotlinc WallStreet.kt
kotlin WallStreetKt
WallStreet.kt
import java.io.FileOutputStream
import java.io.PrintStream
import java.util.*

val LOGGER = PrintStream(FileOutputStream("log.txt", true))
const val DEBUG = false

const val LOG_GAME_HEADER = """
###############
#STARTING GAME#
###############"""

data class Stock(val type : Int, val amount : Int) {

    operator fun minus(amount : Int) = copy(amount = this.amount - amount)
    operator fun plus(amount: Int) = copy(amount = this.amount + amount)
    fun setAmount(amount: Int) = copy(amount = amount)

    operator fun minus(other : Stock) : Stock {
        assert(type == other.type)
        return copy(amount = this.amount - other.amount)
    }

    operator fun plus(other : Stock) : Stock {
        assert(type == other.type)
        return copy(amount = this.amount + other.amount)
    }

    override fun toString() = "$type:$amount"
}

data class Offer(val offer: Stock, val payment: Int) {
    override fun toString() = "$offer@$payment"
}

fun parseStock(repr : String) : Stock {
    val data = repr.split(":").map { it.toInt() }
    return Stock(data[0], data[1])
}

fun parseOffer(repr: String) : Offer {
    val data = repr.split("@")
    return Offer(parseStock(data[0]), data[1].toInt())
}

fun parseOffers(repr: String) = if (repr == "") emptyList<Offer>() else repr.split(";").map { parseOffer(it) }


interface Player {
    fun secretValue(stockType: Int, value: Int)
    fun makeOffer(currentStock: List<Stock>) : Offer?
    fun acceptOffer(offers: List<Offer>) : Offer?
    fun acceptedOffers(offers: List<Offer>)

    var random : Random
}

fun main(args : Array<String>) {

    try {

        if (DEBUG) {
            LOGGER.println(LOG_GAME_HEADER)
        }
        //Change bot name here
        val player = WallStreet()

        while (true) {
            val function = readLine()
            function ?: return
            val line = readLine()!!
            if (DEBUG) {
                LOGGER.println("\nInput:")
                LOGGER.println(function)
                LOGGER.println(line)
            }
            var result : Any
            try {
                result = when (function) {
                    "SecretValue" -> {
                        val data = line.split(":").map { it.toInt() }
                        player.secretValue(data[0], data[1])
                    }
                    "MakeOffer" -> player.makeOffer(line.split(";").map { parseStock(it) }) ?: ""
                    "AcceptOffer" -> player.acceptOffer(parseOffers(line)) ?: ""
                    "AcceptedOffers" -> player.acceptedOffers(parseOffers(line))
                    "RandomSeed" -> player.random = Random(line.toLong())
                    else -> return        //Exit program
                }
                if (function == "AcceptOffer" && result.toString() !in line) {
                    throw Exception("Offer not among available offers!!!!\nResult: $result\nParsed Available Offers: ${parseOffers(line)}")
                }
            } catch (e : Exception) {
                LOGGER.println("Turn #${player.turn}")
                LOGGER.println("\nInput:")
                LOGGER.println(function)
                LOGGER.println(line)
                throw e
            }

            if (result == Unit) {
                result = ""
            }
            if (DEBUG) {
                LOGGER.println("Output:")
                LOGGER.println(result)
            }

            println(if (result == Unit) "" else result)
        }
    } catch (e : Exception) {
        e.printStackTrace(LOGGER)
        throw e
    } finally {
        LOGGER.close()
    }
}


// ###################################################
// #          Put program logic below here.          #
// ###################################################


const val DEFAULT_STOCK_VALUE = 333
const val MAX_TURNS = 1000
const val MAX_STOCK_VALUE = 1000

class WallStreet : Player {

    var secretStockType = 0
    var secretStockValue = 0
    override var random = Random()


    var turn = 0
    val stockPriceStatistics = mutableMapOf<Int, DoubleSummaryStatistics>()

    override fun secretValue(stockType: Int, value: Int) {
        secretStockType = stockType
        secretStockValue = value
    }

    override fun makeOffer(currentStock: List<Stock>): Offer {
        val stock = currentStock[random.nextInt(currentStock.size)]
        val type = stock.type
        val amount = random.nextInt(stock.amount)
        val price = getSellPrice(type) * amount
        return Offer(Stock(type, amount), Math.ceil(price).toInt())
    }

    override fun acceptOffer(offers: List<Offer>): Offer? {
        var bestOffer : Offer? = null
        var mostProfit = 0.0
        for (offer in offers) {
            val offerProfit = profitOfOffer(offer)
            if (offerProfit > mostProfit) {
                bestOffer = offer
                mostProfit = offerProfit
            }
        }
        if (bestOffer != null && bestOffer !in offers) {
            throw IllegalStateException("Tried to accept non-existent offer.\nOffer:  $bestOffer\nAvailable Offers: ${offers.joinToString(";")}")
        }
        return bestOffer
    }

    override fun acceptedOffers(offers: List<Offer>) {
        turn++
        for ((stock, payment) in offers) {
            val stats = stockPriceStatistics.getOrPut(stock.type) { DoubleSummaryStatistics() }
            for (i in 1..stock.amount) {
                stats.accept(payment.toDouble() / stock.amount)
            }
        }
    }

    private fun getSellPrice(type: Int): Double {
        var price = getPrice(type)
        if (price < 1000) {
            price += (1000 - price) * (MAX_TURNS - turn) / MAX_TURNS
        }
        return if (type == secretStockType) Math.max(secretStockValue.toDouble(), price) else price
    }

    private fun getPrice(type: Int): Double {
        return stockPriceStatistics[type]?.average ?: DEFAULT_STOCK_VALUE.toDouble()
    }

    private fun profitOfOffer(offer: Offer): Double {
        return getBuyPrice(offer.offer.type) * offer.offer.amount - offer.payment
    }

    private fun getBuyPrice(type: Int): Double {
        var price = getPrice(type)
        price = price * turn / MAX_TURNS
        return if (type == secretStockType) Math.min(secretStockValue.toDouble(), price) else Math.min(price, MAX_STOCK_VALUE.toDouble())
    }

}

command.txtdosya adına ihtiyaç duymaz. Güzel mesaj!
Nathan Merrill,

Dize enterpolasyonunun sadece $ değil, {} ile yapıldığını sanıyordum.
Socratic Phoenix

@SocraticPhoenix $sadece değişken bir adla çalışır. ${}isteğe bağlı kod yürütür. Temel olarak, her iki şekilde de çalışır ve diş telleri olmadan tercih ederim.
TheNumberOne,

Bilginize: geçici bir çözüm olarak, bu dosyayı çalıştırmak isteyen pencere kullanıcılarının aşağıdakileri değiştirmesi gerekir command.txt: kotlinc-> kotlinc.batve kotlin->kotlin.bat
Nathan Merrill

Kontrolörümü düzelttikten sonra, bu bot bir sürü kötü veriyi geri göndermeye başladı, ben de rekabeti kaldırdım. İstersen sohbet odasında sana yardım edebilirim :)
Nathan Merrill

1

UncleScrooge, Java

import java.util.List;
import com.ppcg.stockexchange.*;

public class UncleScrooge extends Player {
    public Offer acceptOffer(List<Offer> offers) {
        Offer offer;
        try {
            offer = offers.get(0);
        } catch (Exception ex) {
            return null;
        }
        if (offer.getPayment() < 100)
            return offer;
        else
            return null;
    }
    public Offer makeOffer(List<Stock> currentStock){
        if (this.getRandom().nextDouble() < 0.6)
            return new Offer(currentStock.get(secretStockType).setAmount(1), Integer.MAX_VALUE);
        else
            return null;
    }
    public void secretValue(int stockType, int value) {
        super.secretValue(stockType, value);
    }
    public void acceptedOffers(List<Offer> acceptedOffers) { }
}

Hisse senedini gerçekten yüksek bir fiyata sat ve sadece fiyat 100'den azsa al.


1

Profiteer, Java

Profiteer para için var ve her zaman para sayar. Ne kadar para kazandığı konusunda muhafazakar bir tahmin yapar. Daha sonra değerden düşükse gizli hisse senedini satın alır veya ucuz hisse senetlerini satın alır. Ayrıca her şey için ne kadar para ödediğini hatırlıyor ve her zaman borsa fiyatının üzerinde teklif veriyor. Ayrıca, daha az parası varsa daha yüksek tekliflerde bulunacaktır.

Not: Bunu doğru yaptığımı düşünüyorum, ama @NathanMerrill hata kodumu gözden geçirmeyi göze alamazsa, harika olurdu

import com.ppcg.stockexchange.Offer;
import com.ppcg.stockexchange.Player;
import com.ppcg.stockexchange.Stock;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

public class Profiteer extends Player {
    private List<StockInfo> onMarket;
    private List<StockInfo> stocks;
    private int money;
    private boolean first = true;

    @Override
    public Offer acceptOffer(List<Offer> offers) {
        Offer finalOffer;

        Optional<Offer> offer = offers.stream().filter(o -> o.getOffer().getType() == this.secretStockType && o.getPayment() < this.secretStockValue * o.getOffer().getAmount()).sorted((a, b) -> Integer.compare((this.secretStockValue * a.getOffer().getAmount()) - b.getPayment(), (this.secretStockValue * b.getOffer().getAmount()) - b.getPayment())).findFirst();
        if (offer.isPresent()) {
            finalOffer = offer.get();
        } else {
            finalOffer = offers.stream().sorted((a, b) -> Integer.compare(a.getPayment(), b.getPayment())).findFirst().orElse(null);
        }

        if (finalOffer == null || this.money <= finalOffer.getPayment()) {
            return null;
        } else {
            this.stocks.add(new StockInfo(finalOffer.getOffer(), finalOffer.getPayment()));
            this.refreshMoney();
            return finalOffer;
        }
    }

    @Override
    public Offer makeOffer(List<Stock> stocks) {
        if (this.first) {
            this.init(stocks);
        } else {
            this.refreshMarketList(stocks);
        }

        Optional<StockInfo> least = this.stocks.stream().sorted((a, b) -> Integer.compare(a.getBoughtPrice(), b.getBoughtPrice())).findFirst();
        Optional<StockInfo> secret = this.stocks.stream().filter(stockInfo -> stockInfo.getStock().getType() == this.secretStockType).sorted((a, b) -> Integer.compare(a.getBoughtPrice(), b.getBoughtPrice())).findFirst();

        StockInfo finalOffer;
        int price;
        if (secret.isPresent()) {
            finalOffer = secret.get();
        } else if (least.isPresent()) {
            finalOffer = least.get();
        } else {
            return null;
        }

        this.onMarket.add(finalOffer);
        this.stocks.remove(finalOffer);
        price = this.calculatePrice(finalOffer.boughtPrice);
        return new Offer(new Stock(finalOffer.getStock().getType(), finalOffer.getStock().getAmount()), price);
    }

    private int calculatePrice(int boughtPrice) {
        return (int) (boughtPrice + ((boughtPrice / (double) this.money) * this.money)) + 1;
    }

    private void refreshMarketList(List<Stock> stocks) {
        this.stocks.addAll(this.onMarket.stream().filter(stockInfo -> stocks.contains(stockInfo.getStock())).collect(Collectors.toList()));
        this.onMarket.clear();
    }

    private void refreshMoney() {
        this.money = this.stocks.stream().mapToInt(info -> this.secretStockType == info.getStock().getType() ? this.secretStockValue : 5).reduce((a, b) -> a + b).orElseGet(() -> 0) - this.stocks.stream().mapToInt(StockInfo::getBoughtPrice).reduce((a, b) -> a + b).orElseGet(() -> 0);
    }

    private void init(List<Stock> stocks) {
        this.stocks = stocks.stream().map(stock -> new StockInfo(stock, 0)).collect(Collectors.toList());
        this.onMarket = new ArrayList<>();
        this.money = 0;
        this.first = false;
        this.refreshMoney();
    }

    private static class StockInfo {
        private Stock stock;
        private int boughtPrice;

        public StockInfo(Stock stock, int boughtPrice) {
            this.stock = stock;
            this.boughtPrice = boughtPrice;
        }

        public Stock getStock() {
            return this.stock;
        }

        public int getBoughtPrice() {
            return this.boughtPrice;
        }

    }

}

borç ve hala hisse senetleri ile gidebilirsiniz ...
noɥʇʎԀʎzɐɹƆ

@AgentCrazyPython Biliyorum, ancak profesör risk almak istemiyor
Socratic Phoenix

geri çekilemez
noɥʇʎԀʎzɐɹƆ

@AgentCrazyPython meh, sorun değil, oyun eğlenceli ve önemli olan da bu
Socratic Phoenix

1

MaxBot, Java

Bu bot her işlemden en fazla karı elde etmeye çalışır. Satış yaparken, 250 $ satın alırken bilinmeyen bir hisse senedinin fiyatı 300 $ 'a yükseliyor.

import java.util.List;
import com.ppcg.stockexchange.*;
public class MaxBot extends Player {
    int toSell;
    int sellPrice;

    public void secretValue(int stockType, int value) {
        super.secretValue(stockType, value);
        toSell = stockType;
        sellPrice = (value + 1000)/2;
    }
    public Offer acceptOffer(List<Offer> offers) {
        Offer max = null;
        int maxDif = 0;
        for(Offer o: offers){
            int price = secretStockType == o.getOffer().getType()? secretStockValue: 250;
            int val = price * o.getOffer().getAmount();
            int dif = val - o.getPayment();
            if(maxDif < dif){
                max = o;
                maxDif = dif;
            }
        }
        return max;
    }
    public Offer makeOffer(List<Stock> currentStock){
        if(toSell == -1){
            return null;
        }
        int sum = 0;
        for (Stock s: currentStock){
            if(s.getType() == toSell){
                sum += s.getAmount;
            }
        }
        int n = sum - sum/2;
        return new Offer(new Stock(toSell, n), n * sellPrice);
    }
    public void acceptedOffers(List<Offer> acceptedOffers) {
        int highStock = -1;
        int highPrice = 0;
        int markup = 0;
        for(Offer o: offers){
            int trueVal = secretStockType == o.getOffer().getType()? secretStockValue: 250;
            int marketVal = o.getPayment()/o.getOffer().getAmount();
            if(marketVal - trueVal > markup){
                highStock = o.getOffer().getType();
                highPrice = marketVal;
                markup = marketVal - trueVal;
            }
        }
        toSell = highStock;
    }
}

1

BlackMarket, Java

Bunun hakkında söylenecek fazla bir şey yok, bu işlemlerin gerçekleşeceğini görünce ... çizelgelerin dışında, diyebilirsiniz.

import java.util.List;
import com.ppcg.stockexchange.*;

public class BlackMarket extends Player {
    private boolean approvedBySEC = false;
    private int ammoLeft = 30;
    public String taxView = "We want higher tax rates";
    public String excuse = "I never saw that in my life";

    public void secretValue(int drugType, int warrantForMyArrest) {
        super.secretValue(drugType, warrantForMyArrest);
        if (warrantForMyArrest != 0 || drugType == 420) {
            ammoLeft += 10;
        }
    }

    public Offer acceptOffer(List<Offer> offers) {
        for (Offer offer : offers) {
            if (this.approvedBySEC || offer.getPayment() < 9)
                return offer;
        }
        return null;
    }


    public Offer makeOffer(List<Stock> currentStock) {
        return new Offer(new Stock(0,1),420);
    }
}

return null dışındadır ... lütfen düzgünce girin.
noɥʇʎԀʎzɐɹƆ

1
@AgentCrazyPython Teşekkürler! Karanlık döndüğünde "return null" u alacağız. Gelecek ay boyunca seni takip eden arabalara karşı dikkatli ol.
Timtech

1
Neden aşağı oy? Son yarışmaya dördüncü olduk. Her ne kadar tam olarak emin
olmasak da

0

NotQuiteABanksBest Arkadaş, Python 3

Command.txt:

python3 NotQuiteABanksBestFriend.py
NotQuiteABanksBestFriend.py
import random
from functools import total_ordering
from io import StringIO

log = StringIO()
log.write("\n\n~~~NEW GAME~~~\n\n")

LIST_DELIMITER = ';'
STOCK_DELIMITER = ':'
OFFER_DELIMITER = '@'

JAVA_MAX_INT = 2147483647

@total_ordering
class Stock:
    @staticmethod
    def parse(string: str):
        return Stock(*map(int, string.split(STOCK_DELIMITER)))

    def __init__(self, stock_type: int, amount: int):
        self.type = stock_type
        self.amount = max(amount, 0)

    def __str__(self):
        return "T%sx%s"%(self.type, self.amount)

    def __repr__(self):
        return str(self.type)+STOCK_DELIMITER+str(int(self.amount))

    def __bool__(self):
        return bool(self.amount)

    def __eq__(self, other):
        return self.amount == other.amount

    def __lt__(self, other):
        return self.amount < other.amount

    def update(self, amount) -> 'Stock':
        return Stock(self.type, amount)

    def __mul__(self, other: int) -> 'Stock':
        return self.update(self.amount*other)

    def __floordiv__(self, other: int) -> 'Stock':
        return self.update(self.amount//other)

    def __add__(self, other: int) -> 'Stock':
        return self.update(self.amount+other)

    def __sub__(self, other: int) -> 'Stock':
        return self.update(self.amount-other)


class Offer:
    @staticmethod
    def parse(string: str) -> 'Offer':
        try:
            stock, price = string.split(OFFER_DELIMITER)
        except ValueError:
            raise Exception("Cannot unpack "+string)
        return Offer(Stock.parse(stock), int(price.strip()))

    def __init__(self, stock: Stock, price: int):
        self.stock = stock
        self.price = price
        try:
            self.price_per_unit = self.price/self.stock.amount
        except ZeroDivisionError:
            self.price_per_unit = float('inf')

    def __str__(self):
        return "%s$%s"%(self.stock, self.price)

    def __repr__(self):
        return repr(self.stock)+OFFER_DELIMITER+str(int(self.price))


def read_stock_value(value: str):
    global hidden_price, hidden_stock
    stock, price = value.split(STOCK_DELIMITER)
    hidden_price = float(price)
    hidden_stock = int(stock)
    log.write("Hidden StockID: %s\nHidden Price: %s\n"%(hidden_stock, hidden_price))

def process_input():
    handlers = {
        "SecretValue": read_stock_value,
        "RandomSeed": read_seed,
        "MakeOffer": make_offer,
        "AcceptOffer": accept_offer,
        "AcceptedOffers": accepted_offers,
    }
    method = input().strip()
    data = input().strip()
    output = handlers[method](data)
    if output is not None:
        print(repr(output))
    else:
        print()

def read_seed(seed: str):
    random.seed(int(seed))

def start():
    while True:
        process_input()

hidden_stock = None
hidden_price = None

def filter_offers(offer):
    if offer.stock.amount == 0:
        return False
    if offer.price_per_unit > 1000:
        return False
    return True

def certain_profit(offer):
    stock = offer.stock
    if stock.type == hidden_stock and offer.price_per_unit < hidden_price:
        log.write("Offer, %s is certainly profitable.\n"%offer)
        return True
    return False

def make_offer(current_stock: str):
    current_stock = list(map(Stock.parse, current_stock.split(LIST_DELIMITER)))
    own_stock = [stock for stock in current_stock if stock.type == hidden_stock]
    if own_stock and own_stock[0]:
        own_stock = own_stock[0]
        amount_sold = min(random.randrange(1,50), own_stock.amount)
        price = hidden_price+random.randrange(10,50)
        return Offer(Stock(hidden_stock, amount_sold), price*amount_sold)
    sell_stock = random.choice(current_stock)
    amount_sold = min(random.randrange(1,50), sell_stock.amount)
    price = random.randrange(1000, JAVA_MAX_INT//(amount_sold or 1))
    return Offer(Stock(sell_stock.type, amount_sold), price*(amount_sold or 1))

def accept_offer(available_offers: str):
    available_offers = list(map(Offer.parse, available_offers.split(LIST_DELIMITER)))
    filtered_offers = list(filter(filter_offers, available_offers))
    profitable = list(filter(certain_profit, filtered_offers))
    rtn_list = filtered_offers
    if profitable:
        log.write("Profitable: %s\n"%profitable)
        rtn_list = profitable
    if not rtn_list:
        return None
    accepted_offer = min(rtn_list, key=lambda offer: offer.price_per_unit)
    log.write("Bidded for %s\n"%accepted_offer)
    return accepted_offer

def accepted_offers(offers: str):
    pass


if __name__ == "__main__":
    try:
        start()
    finally:
        log.close()

Her zaman gizli stoğu değerinden daha fazla satmaya çalışır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.